I'm trying to show the Google Optimize variant in Google Tag Manager.
I tried to implement it by "Custom JavaScript Variable":
function() {
var property = window.keys(gaData);
var experiment_nr = window.keys(window.gaData[property].experiments);
var experiment_value = window.values(window.gaData[property].experiments).toString()
if (experiment_value == "") {
return "0"
} else {
return experiment_value
}
}
This is the result of it:
Then I tried to test my code with a 5 sec delayed trigger:
And this is the result of the DevTools JS console:
As you can see, the console does not accept it with GTM but accepts it when I type it manually in.
Can someone help me there?
The answer was actually quite simple.
Google Optimize uses a cookie called _gaexp.
There, you get a string summing up the Google Optimize experiment ID as well as the version at the very end:
GAX1.2.wHL2IJUnSg2n8PB4iQH66w.18362.1
All I had to do was to create a new variable reading the cookie:
New variable
1st Party Cookie with the cookie name "_gaexp"
You can of course get the cookie name with JavaScript by simply calling Cookies.get('_gaexp') from the DevTools Console (to check if the cookie value is right)
The _gaexp value has to be manipulated to isolate the variant:
New variable
Custom JavaScript
Add the following code:
function (){
if ({{GA_Optimize_Variable}}=='undefined'){
return '0'
} else {
return {{GA_Optimize_Variable}}.charAt({{GA_Optimize_Variable}}.length-1)
}
}
The _gaexp is not existant when Google Optimize leads your traffic to the original variant of the website. Therefore, a if statement is needed.
Finally, you can use your variable in Google Analytics events and/or dimension.
Try to using dataLayer instead of window object.
I am writing an iframe based facebook app. Now I want to use the same html page to render the normal website as well as the canvas page within facebook. I want to know if I can determine whether the page has been loaded inside the iframe or directly in the browser?
Browsers can block access to window.top due to same origin policy. IE bugs also take place. Here's the working code:
function inIframe () {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
top and self are both window objects (along with parent), so you're seeing if your window is the top window.
When in an iframe on the same origin as the parent, the window.frameElement method returns the element (e.g. iframe or object) in which the window is embedded. Otherwise, if browsing in a top-level context, or if the parent and the child frame have different origins, it will evaluate to null.
window.frameElement
? 'embedded in iframe or object'
: 'not embedded or cross-origin'
This is an HTML Standard with basic support in all modern browsers.
if ( window !== window.parent )
{
// The page is in an iframe
}
else
{
// The page is not in an iframe
}
I'm not sure how this example works for older Web browsers but I use this for IE, Firefox and Chrome without an issue:
var iFrameDetection = (window === window.parent) ? false : true;
RoBorg is correct, but I wanted to add a side note.
In IE7/IE8 when Microsoft added Tabs to their browser they broke one thing that will cause havoc with your JS if you are not careful.
Imagine this page layout:
MainPage.html
IframedPage1.html (named "foo")
IframedPage2.html (named "bar")
IframedPage3.html (named "baz")
Now in frame "baz" you click a link (no target, loads in the "baz" frame) it works fine.
If the page that gets loaded, lets call it special.html, uses JS to check if "it" has a parent frame named "bar" it will return true (expected).
Now lets say that the special.html page when it loads, checks the parent frame (for existence and its name, and if it is "bar" it reloads itself in the bar frame. e.g.
if(window.parent && window.parent.name == 'bar'){
window.parent.location = self.location;
}
So far so good. Now comes the bug.
Lets say instead of clicking on the original link like normal, and loading the special.html page in the "baz" frame, you middle-clicked it or chose to open it in a new Tab.
When that new tab loads (with no parent frames at all!) IE will enter an endless loop of page loading! because IE "copies over" the frame structure in JavaScript such that the new tab DOES have a parent, and that parent HAS the name "bar".
The good news, is that checking:
if(self == top){
//this returns true!
}
in that new tab does return true, and thus you can test for this odd condition.
The accepted answer didn't work for me inside the content script of a Firefox 6.0 Extension (Addon-SDK 1.0): Firefox executes the content script in each: the top-level window and in all iframes.
Inside the content script I get the following results:
(window !== window.top) : false
(window.self !== window.top) : true
The strange thing about this output is that it's always the same regardless whether the code is run inside an iframe or the top-level window.
On the other hand Google Chrome seems to execute my content script only once within the top-level window, so the above wouldn't work at all.
What finally worked for me in a content script in both browsers is this:
console.log(window.frames.length + ':' + parent.frames.length);
Without iframes this prints 0:0, in a top-level window containing one frame it prints 1:1, and in the only iframe of a document it prints 0:1.
This allows my extension to determine in both browsers if there are any iframes present, and additionally in Firefox if it is run inside one of the iframes.
I'm using this:
var isIframe = (self.frameElement && (self.frameElement+"").indexOf("HTMLIFrameElement") > -1);
Use this javascript function as an example on how to accomplish this.
function isNoIframeOrIframeInMyHost() {
// Validation: it must be loaded as the top page, or if it is loaded in an iframe
// then it must be embedded in my own domain.
// Info: IF top.location.href is not accessible THEN it is embedded in an iframe
// and the domains are different.
var myresult = true;
try {
var tophref = top.location.href;
var tophostname = top.location.hostname.toString();
var myhref = location.href;
if (tophref === myhref) {
myresult = true;
} else if (tophostname !== "www.yourdomain.com") {
myresult = false;
}
} catch (error) {
// error is a permission error that top.location.href is not accessible
// (which means parent domain <> iframe domain)!
myresult = false;
}
return myresult;
}
Best-for-now Legacy Browser Frame Breaking Script
The other solutions did not worked for me. This one works on all browsers:
One way to defend against clickjacking is to include a "frame-breaker" script in each page that should not be framed. The following methodology will prevent a webpage from being framed even in legacy browsers, that do not support the X-Frame-Options-Header.
In the document HEAD element, add the following:
<style id="antiClickjack">body{display:none !important;}</style>
First apply an ID to the style element itself:
<script type="text/javascript">
if (self === top) {
var antiClickjack = document.getElementById("antiClickjack");
antiClickjack.parentNode.removeChild(antiClickjack);
} else {
top.location = self.location;
}
</script>
This way, everything can be in the document HEAD and you only need one method/taglib in your API.
Reference: https://www.codemagi.com/blog/post/194
I actually used to check window.parent and it worked for me, but lately window is a cyclic object and always has a parent key, iframe or no iframe.
As the comments suggest hard comparing with window.parent works. Not sure if this will work if iframe is exactly the same webpage as parent.
window === window.parent;
Since you are asking in the context of a facebook app, you might want to consider detecting this at the server when the initial request is made. Facebook will pass along a bunch of querystring data including the fb_sig_user key if it is called from an iframe.
Since you probably need to check and use this data anyway in your app, use it to determine the the appropriate context to render.
function amiLoadedInIFrame() {
try {
// Introduce a new propery in window.top
window.top.dummyAttribute = true;
// If window.dummyAttribute is there.. then window and window.top are same intances
return !window.dummyAttribute;
} catch(e) {
// Exception will be raised when the top is in different domain
return true;
}
}
Following on what #magnoz was saying, here is a code implementation of his answer.
constructor() {
let windowLen = window.frames.length;
let parentLen = parent.frames.length;
if (windowLen == 0 && parentLen >= 1) {
this.isInIframe = true
console.log('Is in Iframe!')
} else {
console.log('Is in main window!')
}
}
It's an ancient piece of code that I've used a few times:
if (parent.location.href == self.location.href) {
window.location.href = 'https://www.facebook.com/pagename?v=app_1357902468';
}
If you want to know if the user is accessing your app from facebook page tab or canvas check for the Signed Request. If you don't get it, probably the user is not accessing from facebook.
To make sure confirm the signed_request fields structure and fields content.
With the php-sdk you can get the Signed Request like this:
$signed_request = $facebook->getSignedRequest();
You can read more about Signed Request here:
https://developers.facebook.com/docs/reference/php/facebook-getSignedRequest/
and here:
https://developers.facebook.com/docs/reference/login/signed-request/
This ended being the simplest solution for me.
<p id="demofsdfsdfs"></p>
<script>
if(window.self !== window.top) {
//run this code if in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "in frame";
}else{
//run code if not in an iframe
document.getElementById("demofsdfsdfs").innerHTML = "no frame";
}
</script>
if (window.frames.length != parent.frames.length) { page loaded in iframe }
But only if number of iframes differs in your page and page who are loading you in iframe. Make no iframe in your page to have 100% guarantee of result of this code
Write this javascript in each page
if (self == top)
{ window.location = "Home.aspx"; }
Then it will automatically redirects to home page.
Here in my javascript function im using location.href as follows
location.href = "../Floder1/result.jsp"; it is working fine but when i used fortify tool it is showing Cross-site Scripting which can result in the browser executing malicious code. how to protect this from cross site scripting. Thank you very much,your answer will be very much appreciated.
This code should work only in firefox since Proxy isn't implemented in all browsers
What you can do is to replace the original location object with a proxied one where you add some logic to your proxy to check for allowed value for location. this will not protect against the direct modification of the original object (location) but if you use only the proxied object in your code you should be fine.
// suppose we are in example.com
let validator = {
set: function(obj, prop, val) {
if (prop === 'href') {
if(typeof val != 'string'){
throw new TypeError('href must be string.');
}
if (!val.startsWith("https://example.com/")) {
throw new Error('XSS');
}
}
obj[prop] = val;
return true;
},
get: function(obj, prop){
return prop in obj?
obj[prop] :
null;
}
};
let proxiedLocation = new Proxy(location, validator);
console.log(proxiedLocation.href);// work same as location.href
proxiedLocation.href = "https://example.com/page1";// work fine
proxiedLocation.href = "https://example.net/page1";// cause exception
The Cross-site Scripting occurs when the user can put data in the webpage or get session data for example.
HOW PROTECT
You never allow inject code in your webpage. So, if you have a form, check it in the server and parse it before print in your page.
You shouldn't allow that the page content is changed by the href. You always escape the data before!.
Read this answer about location.href: https://stackoverflow.com/a/24089350/2389232
SAMPLE:
You have a iframe what changes with a GET variable:
sample.tld/index.jsp?iframe=none.jsp
I can inject a script to your iframe so you should protect it with escape characters:
// Escape the characters in the server and send it to the client.
// So the variable GET iframe will be valid
I don't know why this doesnt work. Although im sure its something to do with the way im handling the url in the if statement. My Jquery / javascript knowledge if basic.
var url = $(location).attr('href');
if (url == 'http://www.website.com/test/index.html')
{
$('#HomeButton').bind('click', HomeButton);
}
function HomeButton(e) {
e.preventDefault();
doSomething....
};
Don't use jquery to access standard object properties.
You can do
if (document.location.href == 'http://www.website.com/test/index.html')
but you should never compare to the whole URL : you'd have wrong result if you change your domain, test elsewhere, use https, add a parameter, etc. You should use the intended property of location, that is pathname :
if (document.location.pathname == '/test/index.html')
In case of doubt, if you want to be sure of your pathname, simply open Chrome's developer tools (by typing F12) and type this on the console : document.location.pathname.
window.location isn't a a DOM element so you can't use jQuery methods on it.
The .href is actually a property of a Location object.
Just use it direct - if (window.location.href === ...)
Hi am trying to get the textbox value of one asp page to other asp page and set the value
here is VBScript which it does
If(disableListHeaderPR()) Then
bEnablePRField = false
Else
bEnablePRField = true
End If
Here disableListHeaderPR() is JS function. I am getting error saying Variable is undefined: 'disableListHeaderPR'
Here is the JS function code
function disableListHeaderPR()
{
if(dateDifference(document.getElementById("txtCommDte").value, "05/04/2012") < 0 )
{
return false;
}
else
{
return true;
}
}
This page has info on calling vbs from js and vice-versa.
http://www.webdeveloper.com/forum/archive/index.php/t-49920.html
But do keep in mind that as long as you are using VBScript, your app won't run as expected in any browser other than IE.
My solution would be to set your variable in the VBScript server-side and then flush the result out to the page in a different JavaScript function that calls your other JavaScript function. Sample (untested) as follows:
<%
Dim bEnablePRField
bEnablePRField = Request.Form("checkboxEnablePRField") <> ""
%>
<script type="text/javascript">
function EnablePRField() {
if (<%=bEnablePRField%> === 'False') {
disableListHeaderPR();
}
}
function disableListHeaderPR() {
if (dateDifference(document.getElementById("txtCommDte").value, "05/04/2012") < 0 ) {
return false;
} else {
return true;
}
}
</script>
Something very similar to that should work for you.
I feel I should point out that, for Classic ASP, the VBScript is only processed server-side so this should work in any browser that supports JavaScript. Before I switched to .Net, I used to pull this trick a lot, and it worked fine in Firefox, as well as IE.
Should you wish instead to use the results of your JavaScript function in your VBScript function, simply store the results of the JavaScript function in a hidden field (e.g., <input id="myResults" name="myResults" type="hidden" />) and then access the value in VBScript (e.g., Request.Form("myResults").
You can also use the hidden field if you are mixing VBScript and JavaScript on the client-side. Just change the way you access the hidden field in VBScript (e.g., document.form("myForm").myResults.value).
Finally, I cannot agree more with techfoobar. If you are mixing VBScript and JavaScript on the client-side, then the only browser it will work in is IE and I would also strongly recommend switching over entirely to JavaScript.
Hope this helps,
Pete