Cross domain iFrame - cookie is not transferred - iframe

we have a website with our application running in an iFrame on multiple domains and subdomains. The main website (www.example.com) has only static content with links to the sites with framed application sites. So sub.example.com, sub2.example.com, search.another.com have all iFrame with the application running.
We'd like to track all these sites with Google Analytics (GA). Subdomain tracking is working fine but I couldn't find a way to make the cross domain work accurately. The main issue is I cannot share the visitor cookie information among the top level domains. So, the same visitor who goes to sub.example.com and search.another.com get 2 different cookies, which result in various issues. (e.g. inflated visitor counter, cannot correctly track referral info, etc)
Can you please help me fix this?
(I've done a pretty thorough search on the web, tried several scenarios but no luck so far)
Here is the core of our GA implementation:
on sub.example.com (and all subdomains of the main website)
_gaq.push(['b._setAccount', 'UA-XXX']);
_gaq.push(['b._setDomainName', 'example.com']);
_gaq.push(['b._setAllowLinker', true]);
_gaq.push(['b._addIgnoredRef', 'example.com']);
_gaq.push(['b._addIgnoredRef', 'search.another.com']);
_gaq.push(['b._trackPageview']);
on search.another.com (all external subdomains have variants)
_gaq.push(['b._setAccount', 'UA-XXX']);
_gaq.push(['b._setDomainName', 'search.another.com']);
_gaq.push(['b._setAllowLinker', true]);
_gaq.push(['b._addIgnoredRef', 'example.com']);
_gaq.push(['b._addIgnoredRef', 'search.another.com']);
_gaq.push(['b._trackPageview']);
just after iframe on all pages
<script type="text/javascript">
_gaq.push(function ()
{
var iFrameTracker = _gat._getTrackerByName('b');
var iframe = document.getElementById('myframe');
iframe.src = iFrameTracker._getLinkerUrl(iframe.src);
});
</script>
on the link on www.example.com
<a href="http://search.another.com" onClick="_gaq.push(function ()
{
var tracker = _gat._getTrackerByName('b');
var linkerUrl = tracker._getLinkerUrl('http://search.another.com');
});">
linkerUrl has the correct Url with the cookie of www.example.com. But for some weird reason, GA assigns a new cookie on the search.another.com. I tried setting the domain name to none (['b._setDomainName', 'none']), which didn't help. I'm not sure if I'm missing a simple fundamental point here. I guess the issue might be related to having cross domain iFrames and the links can be either in the iFrame or in the frameset. So I want to track both.
I do the debugging with the Chrome GA Debugger addon.
(Btw, theoretically we can have infinite number of top-level / sub domains. So manually creating filters for each domain on GA is not an option. )

You're simply assigning the linkerUrl to a variable. You need to redirect the user to that url instead.
You should return false on the onClick handler to keep the browser from doing the usual redirect.
<a href="http://search.another.com" onClick="_gaq.push(function ()
{
var tracker = _gat._getTrackerByName('b');
var linkerUrl = tracker._getLinkerUrl('http://search.another.com');
window.location.href = linkerUrl;
});return false;">
Alternatively you should be using _link. Which does pretty much the same thing.
<a href="http://search.another.com"
onClick="_gaq.push(['b._link', this.href]);return false;">

Related

Server side analytics of outbound links

The problem: We count clicks on external links with Google Analytics (GA). But because external links are opened in a new tab, we are not 100% sure that browser's tab was really opened and that a third-party site was really loaded even in opened tab.
The solution: Do not open direct links to 3-d party web-sites directly in the new tab, but only through some interceptor that will collect statistic on a server side before redirection to the target url. Thus, we will be able to to catch the moment of loading a third page in a new browser window.
Therefore, we need a service that will take full URL as a parameter, collect statistics, and then redirects to the passed URL, like this:
https://magicclickcounter.com/abc?url_to_redirect=http://urltoexternal.link/123 which will collect statistics and redirects to http://urltoexternal.link/123
Any ideas how to achieve this with GoogleAnalytics?
UPD: Firebase DynamicLinks is not appropriate for us because we have to use shortened urls(deep API integration) or there will be no statistic for full urls created manually or via SDK-builder.
UPD: The main problem in our case is that we use a HTML canvas in our page and "clicking area" is inside canvas. Therefore we use next code to open a new window:
this.pixiLayout.App.renderer.view.addEventListener('click', () => {
if (this.pixiLayout.externalUrl) {
window.open(this.pixiLayout.externalUrl, '_blank');
}
});

How to add Google Analytics cross-domain linker parameters to an URL with javascript (using GTM)?

On our site, we have a couple of buttons that will take you to a different domain but not before we've composed the actual URL with appropriate query parameters in Javascript. What is the best way to add Google Analytic's linker parameter to this URL? We're using the universal script injected by Google Tag Manager.
Ah... found it. Documentation suggests:
ga(function(tracker) { var linkerParam = tracker.get('linkerParam'); })
But the tracker is undefined in my case.
I found the solution in this blog post:
if (typeof(window["ga"]) !== "undefined") {
var firstTracker = ga.getAll()[0];
if (firstTracker) { return firstTracker.get("linkerParam"); }
}
But... on further investigation, I found the root cause: using GTM means that there are potentially multiple trackers active on a page. Hence the single ga-function won't work. I haven't found the exact GTM-compatible way of doing this, but I'll stick with this workaround for now.

Custom landing page for SaaS application

I am building a SaaS based web application, to which users can connect using their own domain and apply their company branding to it.
How can I customize the landing page of my application based on domain from which it is being accessed. There is no login information to identify the customer.
Thanks.
On your landing page, you can fetch request url and then customize the response accordingly.
You didn't mention the programming language, however in Java we can use ((HttpServletRequest)request).getRequestURL().toString() to get it.
Recently for one of my projects I used a third party service - www.grooveui.com, it does something similar but without you having to write server side code.
You can try to put in your iframe such code:
<script>
var wantedUrl = (window.location != window.parent.location)
? document.referrer
: document.location.href;
var wantedUrlEsc = escape(wantedUrl);
var newEl = document.createElement('script');
newEl.src = "https://your.server.com?wantedUrlEsc=" + wantedUrlEsc;
document.getElementsByTagName('head')[0].appendChild(newEl);
// or document.head.appendChild(newEl) in modern browsers
</script>
and on server side you can try read and decode the wantedUrlEsc parameter.
Good luck!

Google analytics: two websites and one set of stats?

I have two websites:
http://unit.example.edu
and
http://m.unit.example.edu
The second website is a smartphone version (simplified, just a few pages of basic information) of the first website. The first website already has google analytics code there.
The top of the pages of the first website has code for detecting a visitor's device. If it is smartphone, directs the access to the mobile website. The first website's google analytics code is in the bottom of its pages.
Now I need to put google analytics into the second website.
I hope to be able to see the combined stats of both websites without manual addition. If possible, I also I want to see the stat of just for the second mobile website.
Should I just reuse the google analytics code (see below) in the second website? What is the right way?
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." :
"http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost +
"google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-YYYYYYY-1");
pageTracker._trackPageview();
} catch(err) {}
</script>
Regards.
As requested, an answer.
I'd keep only the UA (Universal Analytics) tracking script on both sites. Make sure you test it first before relying on it to gather data correctly (easily monitored via analytics' real time metrics). Then set the proper views and filters. You can make multiple views to make sure you have everything set up correctly. One view should always be unfiltered (in case something is wrong with one of your filters; GA doesn't save filtered out data).

Problem passing parameters via Iframe in IE

I'm trying to execute an HTTP GET from my website to another website that is brought in via iframe.
On Firefox, you can see in the source that the correct url is in the iframe src along with it's correct parameters-- and it works.
On IE, you can see in the source that the correct url is in the iframe src along with it's correct parameters-- and it doesn't work...
Is there something about IE that doesn't let you pass parameters through an iframe in the querystring?
I've tried refreshing the iframe in IE, I've tried refreshing my page & the iframe in IE, and I've tried copying the url and re-pasting it into the iframe src (forcing it to refresh as if I just entered it into the address bar for that iframe window). Still no luck!
Anyone know why this is happening, or have any suggestions to try to get around this?
Edit: I cannot give a link to this because the site requires a password and login credentials to both our site and our vendor's site. Even though I could make a test account on our site, it would not do any good for the testing process because I cannot do the same for the vendor site. As for the code, all it's doing is creating the src from the backend code on page load and setting the src attribute from the back end...
//Backend code to set src
mainIframe.Attributes["src"] = srcWeJustCreated;
//Front end iframe code
<iframe id="mainIframe" runat="server" />
Edit: Problem was never solved. Answer auto accepted because the bounty expired. I will re-ask this question with more info and a link to the page when our site is closer to going live.
Thanks,
Matt
By the default security settings in IE query parameters are blocked in Iframes. On the security tab under internet options set your security level to low. If this fixes your problem then you know that is your issue. If the site is for external customers then expecting them to turn down their security settings is probably unreasonable, so you may have to find a work around.
Let's say your site is www.acme.com and the iframe source is at www.myvendor.com.
IIRC, most domain-level security settings don't care about the hostname, so add a DNS CNAME to your zone file for myvendor.acme.com, pointed back to www.myvendor.com. Then, in your IFRAME, set the source using your hostname alias.
Another solution might be to have your Javascript set the src to a redirector script on your own server (and, thus, within your domain). Your script would then simply redirect the IFRAME to the "correct" URL with the same parameters.
If it suits you, you can communicate between sites with fragment identifiers. You can find an article here: http://tagneto.blogspot.com/2006/06/cross-domain-frame-communication-with.html
What BYK said. I think what's happening is you are GETting a URL that is too large for IE to handle. I notice you are trying to send variable named src, which is probably very long, over 4k. I ran into this problem before, and this was my code. Notice the comment about IE. Also notice it causes a problem with Firefox then, which is addressed in another comment.
var autoSaveFrame = window.frames['autosave'];
// try to create a temp form object to submit via post, as sending the browser to a very very long URL causes problems for the server and in IE with GET requests.
var host = document.location.host;
var protocol = document.location.protocol;
// Create a form
var f = autoSaveFrame.document.createElement("form");
// Add it to the document body
autoSaveFrame.document.body.appendChild(f);
// Add action and method attributes
f.action = protocol + '//' + host + "/autosave.php"; // firefox requires a COMPLETE url for some reason! Less a cryptic error results!
f.method = "POST"
var postInput = autoSaveFrame.document.createElement('input');
postInput.type = 'text'
postInput.name = 'post';
postInput.value = post;
f.appendChild(postInput);
//alert(f.elements['post'].value.length);
// Call the form's submit method
f.submit();
Based on Mike's answer, the easiest solution in your case would be to use "parameter hiding" to convert all GET parameters into a single URL.
The most scalable way would be for each 'folder' in the URL to consist of the parameter, then a comma, then the value. For example you would use these URLs in your app:
http://example.com/app/param,value/otherparam,othervalue
http://example.com/app/param,value/thirdparam,value3
Which would be the equivalent of these:
http://example.com/app?param=value&otherparam=othervalue
http://example.com/app?param=value&thirdparam=value3
This is pretty easy on Apache with .htaccess, but it looks like you're using IIS so I'll leave it up to you to research the exact implementation.
EDIT: just came back to this and realised it wouldn't be possible for you to implement the above on a different domain if you don't own it :p However, you can do it server-side like this:
Set up the above parameter-hiding on your own server as a special script (might not be necessary if IE doesn't mind GET from the same server).
In Javascript, build the static-looking URL from the various parameters.
Have the script on your server use the parameters and read the external URL and output it, i.e. get the content server-side. This question may help you with that.
So your iframe URL would be:
http://yoursite.com/app/param,value/otherparam,othervalue
And that page would read and display the URL:
http://externalsite.com/app?param=value&otherparam=othervalue
Try using an indirect method. Create a FORM. Set its action parameter to the base url you want to navigate. Set its method to POST. Set its target to your iframe and then create the necessary parameters as hidden inputs. Finally, submit the form. It should work since it works with POST.

Resources