Safe to create cookie before document ready? - javascript

I'm currently saving a cookie in jQuery's document ready event handler, like:
$(function() {
document.cookie = <cookie with info not dependent on DOM>
});
Is it possible and safe to save a cookie even earlier, e.g. as a JavaScript statement outside any event handler that executes as the JavaScript file is being interpreted? Any browsers that may not be reliable to do in?

It is 100% ok to read and write to cookies before the DOM has completed loading if you are not dependent on values from the DOM. If you use the Ghostery extension for Chrome and go to any website you can have a look at the tracking tags that load before the DOM is ready, most of which will be using normal cookies and that will give you an idea of how common it is to do this.

Related

How to prevent Google Tag Manager overwriting document.write()?

We are using Angular for our Website. As not all Pages have been ported to Angular, we implemented a hybrid approach:
Every request goes to Angular first. When it has been loaded, it checks if the Route exists
If not, the HTML-page is fetched from the backend
The html-Element in the DOM (i.e. the complete page) is replaced with the response's body
ngOnInit() {
this.railsService.fetchRailsPage(this.router.url).subscribe(
(response) => this.replaceDOM(response),
(errorResponse) => this.replaceDOM(errorResponse.error)
);
}
private replaceDOM(newContent: string) {
document.open();
document.write(newContent);
document.close();
}
Since all a-hrefs in old pages are plain old hrefs (not Angular's routerLinks), once the user navigates away, the page is reloaded and Angular kicks in again.
So far, it works, but: I noticed that sometimes the DOM is not replaced with the response body.
Debugging brought us to the conclusion that Google Tag Manager could be the issue. It overwrites document.write() and a lot of other default Javascript functions.
Why is that? And how can this be prevented to get the default version of e.g. document.write()?
Seconding Alan here.
Please make sure you're running two tests:
Block gtm with the request blocking function of the dev tools and try reproducing the issue.
Try creating an empty GTM container, loading it on page and reproduce the issue.
If the first test shows that The issue persists with GTM blocked, then it's not GTM.
If the second test shows that the issue is solved, then it's not about GTM but about the logic used in it's configuration.
If anything, I would first make sure no custom code in GTM additionaly overrides document.write (which I've never seen before, but it's definitely possible). Then I would broadly audit all custom scripts deployed by GTM. After that, I would try pausing all the element visibility triggers if any are deployed and seeing if that helps.
GTM likely would aim to override write to be able to watch DOM changes. But it does so gently, adding a bit of tracking there and not changing the essence of it. It's severely unlikely that GTM's core logic would conflict with Angular.
//UPD just had a chat with a colleague on Measure. It looks like the only scenario when GTM overrides the document.write is when there are Custom HTML tags that have an option to "support document.write". The Element Visibility trigger uses mutation and intersection observers rather than listening to document.writes.

Reliably fetching the Google Analytics Tracking ID from another script

I need to retrieve the Google Analytics Tracking ID via JavaScript for use in another script. Something like:
var ga_id = (typeof ga !== 'undefined') ? ga.getAll()[0].get('trackingId') : 'Unable to retrieve GA id'
My Analytics is loaded using Tag manager, so even though I'm running my own JavaScript quite late in the page, its not detecting the presence of the ga object. ( I can access it without a problem via the developer tools console.)
How can I ensure that ga has loaded before trying to access its properties?
It's there on window loaded and you can see it in the GTM preview like so:
I have this CJS in that var (used your code):
Although this is ample in my case, yours may differ, so what you can do is the following:
Make a custom html tag that runs on pageload and deploys a closure with a timeout in it.
In the timeout callback push a dataLayer event.
Now move the tag that you want to get the value of the property id for to the dataLayer event trigger (custom event).
This is not very elegant, but it'll work. Again, for normal implementations, Window Loaded should be ample.

Check if a request is a subresource integrity in a Chrome extension

Is it possible to check if a script/stylesheet is integrity protected via subresource-integrity (SRI) from a Chrome extension?
I want to know this before the request is initiated, so this should be done with chrome.webRequest.onBeforeRequest. But it gives no hints about the request as SRI is browser side. Everything happens after the request has finished.
From my point of view the only way to get this information is to access the DOM directly. This would mean I have to stall all requests until the HTML is completely parsed, which doesn't seem the way to go.
Maybe SRI is just too new to be accessible to extensions, as I didn't find it anywhere in the Chrome extension docs.
Yes, you can determine if a resource is protected by subresource-integrity, prior to the request for the resource being made, by checking for the appropriate attribute(s) (i.e. integrity) on the element specifying the resource as the element is added to the DOM. You can have a content script that is executed at document_start (either specified in manifest.json (run_at), or injected using tabs.executeScript()1 (runAt)). That script could then set up a MutationObserver to watch elements being placed in the DOM. Each appropriate element type (i.e. <script> and <link>) would then need to be checked for using subresource-integrity. This check/determination will occur prior to the webRequest.onBeforeRequest event.
Doing this does not stall all requests until the HTML is fully parsed. It performs the check as each element specifying a resource is entered into the DOM. On the other hand, obviously, any additional processing you introduce through the use of the MutationObserver does add some additional time to parsing the HTML, creating the DOM and loading all resources.
Getting the timing correct to have a script executed at document_start using tabs.executeScript() is non-trivial. How to do so would be a separate question.

How to trigger a js upon the exitting of the web page that created using ASP.NET MVC 5?

I already know this..
$(window).unload(function executebeforeexit() {
...........
});
and this
window.onbeforeunload = executebeforeexit;
function executebeforeexit()
{
................
}
and they did not work for me because they executed even I navigated via the page. This the whole code written in cshtml file.==> https://docs.google.com/document/d/13Huf8uWHTCJzJCWip3sJ4H22oN6rX-rZvgp70Pmd0kk/edit
I want to know how to solve this problem.
for help purpose it would be preferable to have your code shared in a public cloud links (ex.: http://jsbin.com/ , https://jsfiddle.net/ etc. )
usage of :
$(window).unload(callback)
is preferable to
window.onbeforeunload
If you can afford to have jquery loaded
But before going into details, please note that not all browser support having a callback on a page unloading and that it must be synchrone (async execution will never happen)
if you prefer not to use jquery for this purpose, please consider using
window.addEventListener('unload', callback)
It's more clean and allow to have multiples functions as a callback (as you can add multiple listeners) so you make sure your unload callback don't get overwrite somewhere else in your code.
If your page contain iframes or framesets, the listener might be placed on the frame itself if you require it

Phantomjs disable javascript in page but enable included javascript

I am using phantomjs to retrieve CSS information from a page without execute its javascript. For example here is the code snippet.
page.settings.javascriptEnabled = false;
page.open('file:///home/sample.html', function(status) {
if (status !== 'success') {
console.log('Unable to access network');
} else {
page.includeJs("file:///home/sample.js", function() {
var class = page.evaluate(function() {
return document.querySelector('body').className;
});
console.log(class);
});
}
}
If I disabled the javascript, the evaluate function always return null. But when I tried to enable the javascript, the evaluate function will return some value. Is there any idea to disable the javascript in the page, but my included javascript have to work ?
No
page.evaluate() executes JavaScript on the page. If you disable JavaScript in PhantomJS, then you effectively can't use page.evaluate() anymore. And with it goes every way of accessing DOM elements. page.includeJs() will also not work, because it the script cannot be executed on the page.
You can still access page.content which provides access to the current page source (computed source). You may try to use some DOM library to parse the source into a DOM object1 or if the task is simple, you may try to use Regular Expressions.
1 Note that PhantomJS and node.js have different execution environments, so most node.js modules that deal with the DOM won't work
As suggested by Artjom, there is no way to disable execution of the target website JavaScript without disabling PhantomJS ability to execute JavaScript on the page. However, there is a simple way to ensure that no scripts are executed by the target website (which achieves the same result, at the end).
Create a HTTP proxy that intercepts all requests.
Detect responses with Content-Type: text/html.
Remove all <script> tags from the document.
You can configure phantomjs to use proxy using --proxy configuration.
Use http-proxy to create a proxy server.
Use cheerio to remove, comment out, or otherwise invalidate the <script> tags.

Categories

Resources