Google Apps script get Parent URL to iFrame in Javascript
Asked Answered
T

1

7

I've searched many forums and am pretty confident this will be a no, but I thought I would open it up to the community just in case ;)

I've been tasked with creating a tool on our Google Sites pages that records the visit times of our employees after visiting a page. It helps with confirming compliance with document access as well as activity logs. If an iFrame is on the same domain as the page it is hosted on, it's fairly easy to query the URL of the parent page from within the frame, but security limitations restrict this across domains or sub-domains.

I'm hoping that the fact that I am embedding a Google apps script into a Google sites page will give me more options. So far, I have tried the commands document.referrer, parent.document.location, parent.window.document.location, parent.window.location, parent.document.location.href, and the same commands from window and document perspectives. They all respond the same:

  https://n-labp6vtqrpsdn12345neycmicqw7krolscvdkda-0lu-script.googleusercontent.com/userCodeAppPanel

When I want:

 https://sites.google.com/mysite.com/mysite/test/test3

Do any Google veterans have additional tricks?

Edit: I've just tried to pass variables via an html link the Google image placeholder for Apps Scripts on Google Sites and got a tad bit farther. You see, I can run this url: https://script.google.com/a/macros/coordinationcentric.com/s/AKfycbxDX2OLs4LV3EWmo7F9KuSFRljMcvYz6dF0Nm0A2Q/exec?test=hello&test2=howareyou and get the variables test1 and test2 if I run the url in a separate window. If I try to embed that URL into the HTML page on Google Sites, it throws this mixed-content error:

  trog_edit__en.js:1544 Mixed Content: The page at 
 'https://sites.google.com/a/mysite.com/mysite/test/test3' was loaded over HTTPS, but requested an insecure image 'http://www.google.com/chart?chc=sites&cht=d&chdp=sites&chl=%5B%5BGoogle+Apps+Script%27%3D20%27f%5Cv%27a%5C%3D0%2710%27%3D499%270%27dim%27%5Cbox1%27b%5CF6F6F6%27fC%5CF6F6F6%27eC%5C0%27sk%27%5C%5B%22Apps+Script+Gadget%22%27%5D%27a%5CV%5C%3D12%27f%5C%5DV%5Cta%5C%3D10%27%3D0%27%3D500%27%3D197%27dim%27%5C%3D10%27%3D10%27%3D500%27%3D197%27vdim%27%5Cbox1%27b%5Cva%5CF6F6F6%27fC%5CC8C8C8%27eC%5C%27a%5C%5Do%5CLauto%27f%5C&sig=TbGPi2pnqyuhJ_BfSq_CO5U6FOI'. This content should also be served over HTTPS.

Has someone tried that approach, perhaps?

Trombley answered 18/10, 2017 at 20:31 Comment(1)
In my continued search, I found an interesting post at blog.knoldus.com/2011/07/31/…, which involves wrapping the apps script in a xml file and passing the page reference to the app. In my attempts though, I hit another cross-domain error trying to call the hosted script on my site (the main site is a private intranet and can't host public links to a xml file as needed). Has anyone tried something similar successfully?Trombley
C
2

In short - I understand it's not possible to investigate a parent URL from an iFrame in Google Sites.

The content of iframes/embedded content is hosted all over the place, separate from the site itself. The Same-Origin rules prevent checking as you've found.

Your first URL "https://n-labp...googleusercontent.com..." is where the script itself is hosted. Any output from the script, like HTML, will appear to come from here.

You can embed HTML and javascript directly in Sites using the Embed function. If you investigate that, you'll find that it's hosted at something like "https://1457130292-atari-embeds.googleusercontent.com..."

Calling parent will always give this *-atari-based URL, rather then the actual page it's hosted on.

A fairly lightweight solution is to use a combination of the two. Use simple doGet pings and handle the work in your Apps Script.

On your Site, use Embed feature to insert:

<!DOCTYPE html>
<html>
<body onbeforeunload="return depart()">
<script>
var page = "testpage"; // manually set a name for each page you paste this code in to
var script = "https://script.google.com/macros/s/... your script, ending with exec ...";

fetch(script+"?page="+page+"&direction=arrive");

function depart(){
fetch(script+"?page="+page+"&direction=depart");
}
</script>
</body>
</html>

Then in your Apps Script:

function doGet(e){
var httpParams = e.parameter ? e.parameter : "";
// params is an object like {"page": "testpage1", "n": "1"}
var getPage = httpParams.page ? httpParams.page : "";
var getDirection = httpParams.direction ? httpParams.direction : "";

/* Handle it as you please, perhaps like: */

var user = Session.getActiveUser().getEmail();
/* maybe use a temporary active key if open to non-Google users */
/* first-time Google users will have to authenticate, so embed one frame somewhere full-size maybe, or just tell users to go to the script's link */

/* hand off to a helper script */
var time = new Date();
var timeUTC = time.toUTCString(); // I like UTC
doSomethingWithThis(user, direction, timeUTC);
/* etc... */

/* Return some blank HTML so it doesn't look too funny */
return HtmlService.createHtmlOutput("<html><body></body></html>");
}

Then publish as a web app. If you'll use temporary active keys instead of Google accounts, you'll have the script run as you and be available to anyone, even anonymous.

You've probably already solved this, but I hope it can be of use to someone else who stumbles across it!

Cherri answered 1/5, 2019 at 3:40 Comment(1)
This is helpful to me. I was just hoping that you would be completing the function doSomethingWithThis(user, direction, timeUTC); I have webapp and prepared login form and now i want to keep user logged in for some days and then upon expired, user shall be prompted with login form page again. How would I do to keep user logged in?Herta

© 2022 - 2024 — McMap. All rights reserved.