inject GA4 script in the html of a static site with javascript - javascript

I have the following situation:
a static site, only html pages
a cookie notice system, with my own cookies, accept and refuse system of cookies setup
Now I need to inject the GA4 script into the head of pages when cookies are accepted, but...
I have already made made that, by appending the script to the head and it is visible on browser, on page reload with inspect elements...and it's working perfect.
When users click on accept cookies, the cookies accept is saved on client's side, and the script is APPENDED to page.
But I need the GA4 script to be somehow INJECTED, to be visible on the source page. Like when I preview the source page in browser to have it there. I don't need it to be injected into the html file itself, but only into the browser.
I did my own research about these days, and now it's killing me, as all I could find was the append way, but that is not injecting it into the source page on browser.
Any advice or guidance would be greatly appreciated.
Note (as I have been asking all the time. I don't want to offend anyone, but that's the best way I can explain where I want to do and what):
the source page I'm talking about is when right click on browser and view source page (there is where I need the GA4 code to be inserted)
and the way I got it to work is when right click > inspect > elements tab - (there i have it now working)
Thank you!

First question would be, why do you want it to be in the actual source code? A common way of inserting these scripts is through a tag-management-solution, which basically follows similar logic as appending scripts to the page (i.e. similar to what you meant by the inspect elements route).
To answer your question;
There is an option to get it into the sourcecode, and that is by checking on the server delivering the HTML whether a user has accepted the cookies, if that is the case deliver the HTML file (or adjust the HTML) to contain the GA4 script, if the user didn't accept: deliver the page without the GA4 script.
Since you mention these are static HTML files, I assume there is no server in place where this kind of logic can be inserted. So the best option is to insert the script afterwards.
Another way would be to insert the tag by default, but disable tracking (haven't tested the below part, also, verify yourself whether in your situation this actually blocks tracking when cookies aren't accepted):
window['ga-disable-GA_MEASUREMENT_ID'] = true;
https://developers.google.com/analytics/devguides/collection/gtagjs/user-opt-out
You could try to add this in your HTML before loading the GA4 tag, similar to something like:
<script>
const gaMeasurementId = 'G-12345678'; //replace with your own MeasurementID
let cookiesDeclined = true; //default to declined cookies
document.cookie.split(';').forEach( (cookie) =>{ //loop through all cookies
const cookie_arr = cookie.split('='); //get key/value pairs for cookies
let name = cookie_arr[0]; //cookiename
let val = cookie_arr[1]; //cookieval
if(name === 'cookieConsent' && val === 'accepted' ){
cookiesDeclined = false; //set the declined status to false when user has accepted the cookies
}
})
window['ga-disable-'+gaMeasurementId] = cookiesDeclined;
//->insert ga4 tag here
</script>

Related

Setting Cookies for A/B Testing

I am trying to set up an A/B test where the cookie will appear to 50% of the users. I have the option to place the cookie JavaScript in a field called "Head Include" of the targeted page's HTML's head, but the cookie is not appearing. The following is my script:
document.cookie = 'cname=true; Secure';
The cookie works when I place the script code in the HTML's head on the domain's site level. I have place a setting for the cookies to appear at a specific path. See following
document.cookie = 'cname=true; Secure; path=/test';
But I don't want to use the above script because I want to apply the cookie to a targeted page that will only show for 50% of targeted users and not to the site with a designated path assigned because then the cookie will show 100% of the time for that page, thus defeating the purpose of a A/B test.
My question is can a cookie be set on a specific page's HTML head and not the domain's HTML head? (Please note that names have be generalized in the code for privacy reasons)
I am still not sure if I got the problem.
You are using some kind of CMS and this CMS has the option to include scripts on a specific page ("Head include" on the target page) or an all pages ("HTML head" on domain site level). The first does not work, the latter does, but you dont want your cookie script executed on all pages.
Without seeing the generated HTML code of the (not working) target page we can't find out why its not working. If you can post a link to a prepared page (a page where the script is included and the cookie is not created) that could help to solve the problem.
Another option, without knowing the acutal problem would be shipping the script to all pages but filter the actual execution to a specific file path or url parameter. Example:
// let current = new URL(location.href); // use this to get the current url of the browser
let current = new URL('https://www.someurl.net/some_directory/some_file.ext?a=yes&b=12345'); // just an example url
if (current.searchParams.has('a') && current.searchParams.get('a') === 'yes') {
// put your cookie script here, it will be executed only if the url has an a parameter and if that parameter has the value 'yes'
}
Have a look at MDN for an overview of the properties provided by the URL class

I want to redirect to a website and then click on a button on it

I want to redirect my browser to another website and then click on a action button on that website. I think i should add some time delay in between these two tasks. The code i have written do only one event at a time.
window.location.href = "http://www.google.com";
var delayInMilliseconds = 2000;
setTimeout(function() {
document.getElementById('action-button').dispatchEvent(new MouseEvent("click"));
}, delayInMilliseconds);
It's forbidden to do this for security reasons.
In computing, the same-origin policy is an important concept in the
web application security model. Under the policy, a web browser
permits scripts contained in a first web page to access data in a
second web page, but only if both web pages have the same origin. An
origin is defined as a combination of URI scheme, host name, and port
number. This policy prevents a malicious script on one page from
obtaining access to sensitive data on another web page through that
page's Document Object Model.
Source
It is not possible in this manner.
First you change the url of the page which will stop the rest of your JS code from executing. So your timeout will never reach the google page.
Instead implement an <iframe> with the src set to http://www.google.com. Then select the iframe and look for your element in there.
This post will explain how to select the element from an iframe.
Get element from within an iFrame
At the moment you redirect the user with window.location.href any other script won't be executed.
Sort of hack to do what you want is implant script on the second website that will trigger if the user came from a specific URL. Something like that:
var URL = "OLDWEBSITEURL";
var x = window.history.back();
if (x === URL) {
document.getElementById('action-button').dispatchEvent(new MouseEvent("click"));
/* or any other code */
}
Note that if the user open the link on different window/tab or/and disable js it won't work.

Edit cross-domain Iframe content Locally Only

As many of us know there is no way to edit a Cross Domain IFrame due to the Same Origin Policy.
Is there a way around this if we use the Stylish extension etc. locally only?
Take this video being launched inside an iframe for example:
I need to simply add "zoom:2;" onto "#video21588864 iframe figure"
If this is 100% not possible, why am I able to do it successfully in the Inspector window, but not automatically? Is there really ZERO automatic local ways around this using Javascript or something?
There is no way you can access the content inside the <iframe> in a cross-origin fashion. You might be able to if the response includes a CORS header.
Why am I able to do it successfully in the Inspector window
The developer tools is separate from your document. It can do much more things that you cannot possibly do with normal JavaScript in a webpage.
Rationale
There is a reason why you cannot access the content inside an iframe. Consider this, a user was logged into their bank webpage. A token is stored in a cookie to prove that the user is logged in.
Now you include an iframe in your webpage and loads the bank's webpage. Since the cookie contains a valid token, the iframe will show that the user has been logged in.
Wouldn't it be great if you can access the iframe and send yourself some money? Well, this is exactly why it's not allowed, 100% not possible, given that the browser is implemented correctly.
Addendum
I have decided to add this part after seeing that you have mentioned the word locally. Now, I do not know exactly what you are trying to do, but it is possible to manipulate the content inside the iframe if you have an elevated privilege, including:
a userscript
an extension with proper permissions acquired
developer tools
the browser itself
If you merely want to add zoom: 2 to videos from ESPN on your own computer, I would suggest creating a userscript which has a much higher privilege than a normal webpage and much easier to make than an extension.
// ==UserScript==
// #match http://www.espn.com/core/video/iframe*
// ==/UserScript==
document.querySelector("figure").style.zoom = 2;
Save that as myscript.user.js. Open up chrome://extensions and drag that file onto the page. The userscript will have a higher privilege and can access the page.
One way to edit cross-origin domains in an iframe is to load them via the server (PHP) and modify the html by adding a base tag: <base href='http://www.espn.com'/> It's no guarantee that they will let you load all the elements as html and still render the page properly but can work in some cases and is worth the try.
A very simple iframe-loader.php would look like this:
<?php
error_reporting(0);
$url = $_REQUEST['url'];
$html = file_get_contents($url);
$dom = new domDocument;
$dom->strictErrorChecking = false;
$dom->recover = true;
$dom->loadHTML($html);
//Add base tag
$head = $dom->getElementsByTagName('head')->item(0);
$base = $dom->createElement('base');
$base->setAttribute('href',$url);
if ($head->hasChildNodes()) {
$head->insertBefore($base,$head->firstChild);
} else {
$head->appendChild($base);
}
//Print result
echo $dom->saveHTML();
DEMO
Then you load a url by going to /iframe-loader.php?url=http://www.espn.com/core/video/iframe?id=21588864...
Good Luck!

Injecting HTML into existing web pages

I'm interested in the concept of injecting a bit of HTML into existing web pages to perform a service. The idea is to create an improved bookmarking system - but I digress, the specific implementation is unimportant. I'm quite new to web development and so I have no definite idea as to how to accomplish this, thought I have noticed a couple of possibilities.
I found out I can right click > 'inspect element' and proceed to edit my browser's version of the HTML corresponding with the webpage I'm viewing. I assume that this means I can edit what I see and interact with. Could I possibly create a script that ran from a button on bookmarks bar that injected an Iframe which linked to a web service of my making? (And deleted itself after being used).
Could I possibly use a chrome extension to accomplish this? I have no experience with creating extensions and so I have no clue what they're capable of - though I wouldn't be against learning.
Which of these would be best? If they are even valid ideas. Or is there another way that I've yet to know of?
EDIT: The goal is to have a user click a button in the browser if they would like to save this page. They are then presented an interface visually independent of the rest of the page that allows them to categorize this webpage according to their interests. It would take the current link, add some information such as a comment, rating, etc. and add it to the user's data. This is meant as a sort of side-service to a website whose purpose would be to better organize and display the browsing information of the user.
Yes, you can absolutely do this. You're asking about Bookmarklets.
A bookmarklet is just a bookmark where the URL is a piece of JavaScript instead of a URL. They are very simple, yet can be capable of doing anything to a web page. Full JavaScript access.
A bookmarklet can be engaged on any web page -- the user simply has to click the bookmark(let) to launch it on the current page.
Bookmark = "http://chasemoskal.com/"
Bookmarklet = "javascript:(function(){ alert('I can do anything!') })();"
That's all it is. You can create a bookmarklet link which can be clicked-and-dragged onto a bookmark bar like this:
Bookmarklet
Bookmarklets can be limited in size, however, you can load an entire external script from the bookmarklet.
You can do what you refer to as like an <iframe>, so here are some steps that may help you, simply put:
Create an XMLHttpRequest object and make a request for a page trough it.
Make the innerHTML field of an element to hold the resultString of the previous request, aka the HTML structure.
Lets assume you have an element with the id="Result" on your html. The request goes like this:
var req = new XMLHttpRequest();
req.open('GET', 'http://example.com/mydocument.html', true);
req.onreadystatechange = function (aEvt) {
if (req.readyState == 4 && req.status == 200) {
Result.innerHTML = req.responseText;
}
};
req.send(null);
Here's an improved version in the form of a fiddle.
When you're done, you can delete that injected HTML by simply:
Result.innerHTML = '';
And then anything inside it will be gone.
However, you can't make request to other servers due to request policies. They have to be under the same domain or server. Take a look at this: Using XMLHttpRequest on MDN reference pages for more information.

Reading document.links from an IFrame

EDIT:
Just a quick mention as to the nature of this program. The purpose of this program is for web inventory. Drawing different links and other content into a type of hierarchy. What I'm having trouble with is pulling a list of links from a webpage within an IFrame.
I get the feeling this one is gonna bite me hard. (other posts indicate relevance to xss and domain controls)
I'm just trying something with javascript and Iframes. Basically I have a panel with an IFrame inside that goes to whatever website you want it to. I'm trying to generate a list of links from the webpage within the Iframe. Its strictly read only.
Yet I keep coming up against the permission denied problem.
I understand this is there to stop cross site scripting attacks and the resolution seems to be to set the document domain to the host site.
JavaScript permission denied. How to allow cross domain scripting between trusted domains?
However I dont think this will work if I'm trying to go from site to site.
Heres the code I have so far, pretty simple:
function getFrameLinks()
{
/* You can all ignore this. This is here because there is a frame within a frame. It should have no effect ont he program. Just start reading from 'contentFrameElement'*/
//ignore this
var functionFrameElem = document.getElementById("function-IFrame");
console.log("element by id parent frame ");
console.log(functionFrameElem);
var functionFrameData = functionFrameElem.contentDocument;
console.log("Element data");
console.log(functionFrameData);
//get the content and turn it into a doc
var contentFrameElem = functionFrameData.getElementById("content-Frame")
console.log(contentFrameElem);
var contentFrameData = contentFrameElem.contentDocument;
console.log(contentFrameData);
//get the links
//var contentFrameLinks = contentFrameData.links;
var contentFrameLinks = contentFrameData.getElementsByTagName('a');
Goal: OK so due to this being illegal and very similar to XSS. Perhaps someone could point out a solution as to how to locally store the document. I dont seem to have any problems accessing document.links with internal pages in the frame.
Possibly some sort of temp database of cache. The simpler the solution the better.
If you want to read it just for your self and in your browser, you can write a simple proxy with php in your server. the most simple code:
<?php /* proxy.php */ readfile($_GET['url']); ?>
now set your iframe src to your proxy file:
<iframe src="http://localhost/proxy.php?url=http://www.google.com"
id="function-IFrame"></iframe>
now you can access the iframe content from your (local) server.
if you want set the url with a program remember to encode the url (urlencode in php or encodeURIComponent in js)
Here is a bookmarklet you can run on any page (assuming the links are not in an iframe)
javascript:var x=function(){var lnks=document.links,list=[];for (var i=0,n=lnks.length;i<n;i++) {var href = lnks[i].href; list.push(href)};if (list.length>0) { var w=window.open('','_blank');w.document.write(list.length+' links found<br/><ul><li>'+list.sort().join('</li><li>')+'</ul>');w.document.close()}};void(x());
the other way is for you (on Windows) to save your HTML with extension .HTA
Then you can grab whatever lives in the iFrame
You might be interested in using the YQL (Yahoo Query Language) to retrieve filtered results from remote urls..
example of retrieving all the links from the yahoo.com domain

Categories