How to run chrome js snippet before other js files? - javascript

Create chrome snippet like this:
window.my_property = "my_property";
Open any site
Run the snippet
I want to my snippet run before other js scripts on the website. Is it possible? Thanks in advance.

It's possible using Chrome Extensions.
You can write an extension (how to do that is beyond the scope of the answer - see some guides in the docs) that injects a Content Script with "run_at": "document_start" configuration and match patterns that fit the pages you want to inject it to.
Then, your code executes before the page is loaded - it basically consists only of the document node at that point. If you need to manipulate nodes, you're out of luck - some scripts will probably execute before the node is in the tree. If you just want to execute something like the above (modify the window object), you'll be able to do so.
Yet still, you'll need to make it a bit more complicated because of the isolated world principle. You need to use a technique to inject your code into the page.
You can do it way more easily by using a userscript engine like Tampermonkey. Again, you'll need something like
// #run-at document-start
How to write a userscript is, again, beyond the scope of this answer.

The most easy and temporary way to run chrome js Snippets before page load is to put debugger at the top of your HTML page, preferably at head or before the js code which relies on your js snippet.
<head>
<script>
debugger;
</script>
...
Now when the browser is "Paused in debugger", right click on the snippet name and Run it to execute immediately. After that you can resume debugger and continue working on the page as usual.
Please remember, this method is suitable only for testing and requires you to have control over the page (as you need to edit page HTML or JS to put debugger)
If you need to run your js snippet every-time or the page is not in your control, creating an chrome extension is currently the only solution.

Related

Why do websites like Hotjar and Google Analytics use complex tracking code instead of just a <script> tag?

Website that use JS tracking usually use this kind of code :
<script>
(function(h,o,t,j,a,r){
h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
h._hjSettings={hjid:9999,hjsv:5};
a=o.getElementsByTagName('head')[0];
r=o.createElement('script');r.async=1;
r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
a.appendChild(r);
})(window,document,'//static.hotjar.com/c/hotjar-','.js?sv=');
</script>
In the end, those scripts just add a <script> tag to the <head> of the page, so surely there must be a reason why they're doing it this way.
Is it for ad-blocking bypass reasons ? Wouldn't the generated request be the same as if it was hardcoded in the <head> ?
I'm the chief architect at Hotjar so I'll explain the reasons why we did it in this particular way.
We need to do things before the main script is loaded.
h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
That particular line allows us to store actions to execute once the main script is loaded. It allows for things like hj('trackVirtualPageView', '/url') to be called before our script is loaded.
We can store things like settings as part of the snippet.
h._hjSettings={hjid:9999,hjsv:5};
That could absolutely be added as part of the query string when loading the script. The downside of using that approach is that we would get less optimal caching since it would be impossible for a browser to know that script.js?hjid=1 and script.js?hjid=2 actually loads the same JS file.
What we're doing in the last part is actually just creating a <script async=1> tag and adding it to the <head> which works really well. The reason we're doing it through JS is that we like to make it as easy as possible for our users by only asking them to put code in one place.
There might be an even better to do what we're doing which I'm blissfully unaware of, and in case there is, please reach out and tell me about it! :)
At least part of the answer is that vendors want to load their libraries in a way that does not block page rendering.
If the browser hits a script element it tries to get the script source, and might prevent the page from rendering until the complete script is downloaded. In the bad old days it used to happen that website would show up blank, because the (then synchronous) Google Analytics script could not be downloaded in a timely fashion and stopped the page from rendering. Script injection became an accepted method to make scripts non-blocking.
There are other ways (defer, asynch, etc - for historical interest here is a link to an 2009 article that discusses the issue, because the problem is that old), but script injection is a convenient way to set up a few variables along the way (plus if Google does it it must be the best way, or so seems to be the though process with some companies).

How to make a javascript logic not visible in page resource in angularjs?

I am working on a angularjs module in which we are trying to avoid a particular piece of logic in the view source on the browser. I have just given the skeleton code where the logic written inside script tags should not be shown in the page source of the browser.
<html ng-app="myApp">
<head>
<script>
if(something){
do something...
}
<script>
</head>
<body></body>
</html>
Is there any way in angularjs or javascript such that the logic written inside script is not visible in view page source on browser?.
This is not possible as the code needs to be executed by the browser, thus transferred to the client. Anyone can read/copy your code.
The most you can do is to use uglify or similar tool to minify your code. This will have to advantages for you. First, your code will be hard to read for others who might want to exploit your application. But keep in mind, it is still not impossible to understand your code even when minified - it just takes more time. And second, your scripts will become smaller thus making your page load slightly faster.
One more solution is make it look a bit complex so the user trying to read it does not understand it(in case you are not interested in making a minfied version)
Store all the Variables required in a separate file and access them form that file.
Even your base URL should be stored as global variable.
These are some options which you can use but making a minfied code is best practice.
You can't hide code to your client. It is executed in the client browser.
The best thing you can do here is to minify your code. It will make it unreadable without parsing it. Also, the code will be smaller, and will be loaded by the browser faster.
As a side note, luckily all the code is visible: imagine if malicious code could be executed without you know it.

Is it possible to download java script code snippets by ajax, then execute it at run time?

The idea is after the ready() function completes, lets say user clicks a button. Then the java script code behind it will run ajax to retrieve some java script code snippets (as text), then it executes the code just downloaded.
Is it possible? Any frameworks can do it?
You don't even need ajax to do it. You can simply create a new script element with the src attribute set to your JS file and insert it in the DOM (usually in the head element).
var script = document.createElement('script');
script.setAttribute('src', 'myfile.js');
document.head.appendChild(script);
Thanks Tibos for providing me the clues. I used your code to search for what I want, and here it is.
Jan Wolter described his solutions to dynamically load and execute the javascript at run time.
(http://unixpapa.com/js/dyna.html). It seems that the unstable-ness of dynamic JS loading is related to the JS code file size. If JS code file is big, different browsers may behave differently. Jan provided a way to avoid it.
Thanks again.

Javascript script/dom dependency?

When helping someone with a website that is rather large and have many includes I hit a bug and couldn't understand it. It was something like this
<script src=...></script>
<div ...
<script>
alert('myscript');
</script>
This page worked fine until I use that section of html and used jquery to ajax the content in. It broke the code but I don't understand why. I seen my alert. I can see the script is being access via the browser network log. I see some of the results of the first script tag but its broken.
Why does order matter? I thought as long as the dom is ready and the script is executed everything should be fine. But in this case being ajaxed in breaks it. I couldn't spend much time but it was curious to see something was dependent on timing.
--edit--
Also I notice if the script is already included on the page ajaxing in the content it will run fine
Does anyone have any idea why ajaxing in content breaks? When its not ajaxed in its fine.
Based on what you say, I give the following assessment :
40% likely -- it is about script load. Dependencies within the ajaxed script to other scripts, variables you define on the page, or even DOM content that is supposedly loaded could be not loaded at the time the script is ajaxed and executed.
Try changing the order of the script tag on the page, putting the loading of the script inside a document ready event handler, or delaying the script execution with setTimeout or defer="defer" -- or if you are really cool create a boot loader that ensures every script is loaded and executed in the exact order you specify : by chaining sets of dependency free simultaneous loads, to sequences of dependent loads.
Script1 <---- depends on --- (Script 2.1, Script 2.2, Script 2.3 )
<--- depends on --- Script3.
So load 1 first, then all the 2. scripts, then 3.
40% likely -- it is about security model. The website where you are ajaxing it from, Where is that? What is its relation to the domain the page is on? Are you testing this on localhost ?If so there are more restrictions. What about on an actual server? Is the Access-Control-Allow-Origin header set appropriately on the ajax response?
20% likely -- it is a circular dependency between the script and the DOM. Say some event handler on element X closes on a scope that references element X. Then there will be a reference to X inside a reference to X so they can't both be garbage collected, so X will persist, cause a memory leak, and possibly create an unusable reference which could be breaking your code.
--edit--
Based on your comment about .html(...) I think .html or .load to run scripts is too messy, and may not even work at all. See .load() doesn't load scripts for a nice way to load scripts with ajax. Or you could jQuery.getScript(...).
Also I seem to remember having issues even with loading html nodes from plain HTML using ajax. It just seems too messy to me. If you want to transfer structured information across ajax, use JSON, then present that information on your side with javascript and HTML. So, don't grab the whole data + presentation, just grab the data, then do your own presentation on your side. It's much neater.

GWT bookmarket or GWT as an external library

I simply want to load a GWT(Google Web Toolkit) app by adding a script tag to the DOM, however because the GWT linker uses document.write() I'm unable to find any good way of doing so. I've found some hacks for doing so on various blog posts but they all seem to fail with the latest version of GWT. Any reasonably non-invasive approach for doing this come to mind?
Clarification:
Normal way to start up a GWT app, in your host html page:
<script type="text/javascript" language="javascript" src="myapp.nocache.js"></script>
This, of course, starts up as soon as the page loads. I want to do it at a later time:
function startapp() {
var head = document.getElementsByTagName('head');
var s = document.createElement('script');
s.setAttribute('type', 'text/javascript');
s.setAttribute('src', 'myapp.nocache.js');
head[0].appendChild(s);
}
Here's what seems to work so far:
Add this to the top of your App.gwt.xml:
<!-- Cross site linker -->
<inherits name="com.google.gwt.core.Core" />
<add-linker name="xs" />
After compiling your app with the above setting, modify (or copy) the generated app.nocache.js as follows:
1) Comment the last $doc.write... statement
2) Copy this portion from the $doc.write statement you just commented out and eval it. Example:
eval('window.__gwtStatsEvent && window.__gwtStatsEvent({' + 'moduleName:"app", sessionId:window.__gwtStatsSessionId, subSystem:"startup",' + 'evtGroup: "loadExternalRefs", millis:(new Date()).getTime(),' + 'type: "end"});' + 'window.__gwtStatsEvent && window.__gwtStatsEvent({' + 'moduleName:"app", sessionId:window.__gwtStatsSessionId, subSystem:"startup",' + 'evtGroup: "moduleStartup", millis:(new Date()).getTime(),' + 'type: "moduleRequested"});');
3) Add this line right after.
document.body.appendChild(document.createElement('script')).src=base + strongName + ".cache.js";
So you're basically replacing the $doc.write with those two lines.
Now, your bookmarklet will look something like:
My App
I'm assuming you are already using the cross-domain linker and this does not resolve your problem with document.write. If not, it might be worth a look (sorry, not enough experience with it to say.)
One approach that I am fairly sure could be made to work is this:
Your bookmarklet adds a script tag to the page (as now)
This script is not GWT compiler output. It is a plain-old javascript that adds an IFrame to the page, and the src of that IFrame is pointed at an HTML page on your server that loads your GWT module.
Presumably the goal is for your GWT module to get things out of the page it was loaded into. Of course, it can't do this directly in this case because the IFrame comes from a different domain than the parent page.
In order to make this work you would have to use window.postMessage and window.addEventListener to communicate between your GWT module in the IFrame and your javascript stub in the parent (using JSNI on the GWT side.)
If you have to support older browsers, postMessage won't work - but you might be able to get away with hash manipulation - but this is probably where I'd draw a line on practicality.
Whenever a browser loads a javascript file, its also execute every line of it inorder to build the symbol tables etc.
In your case, the app loads in the browser and after the dom is loaded, your GWT module js gets loaded. At this point, the browser will try to execute every line of the GWT module javascript, possibly causing your earlier loaded DOM to go for a toss.
What exactly is your use case? If your requirement is conditionally loading the GWT module then your could try something like this:
Include this in your head:
<script src="gwtmoduleloader.js"></script>
Here, gwtmoduleloader.js is infact a servlet that will hold logic to figure out if the gwt module is to be loaded.
If the GWT module is to be loaded, the sevlet can print a
document.write('<script src="myapp.nocache.js"></script>')
or else return silently.
When browser evaluates the contents of gwtmoduleloader.js, it may find a document.write for another script (in your case the gwt module), which it will load and evaluate. This is thus a conditional load and can be achieved before the body begins loading.
Is this what you were looking for?

Categories