Webkit threading javascript file loadsand execution order - javascript

I am trying to building a XSS widget and am having issues with Webkit browsers loading the external javascript files which I am appending into the dom. It works as below:
Widget.js appends 3 javascript files into the dom (jquery, data, content)
Jquery.js is standard jquery with a custom namespace
Data.js is a javascript array
Content.js is a set of jQuery instructions to build the widget based off the data in Data.js
In firefox the browser does exactly 100% of the time what im telling it and the widget loads where ever you placed the include javascript on the page.
However in Webkit ie Safari, the browser returns the 3 files in a random order, and executes once returned. This means that when Content.js looks for $ to do jquery magic it fails. Likewise if jQuery is available and it loads the data late if fails due to lack of data.
Suggestions please?

The best way to do this is to just concatenate the files on the server--that way you go from making 3 http requests to one, and the scripts are parsed and executed together.
If you can't do that, do you have to add the script tags by appending them to the dom? If you just added them in HTML, it should work:
<script src="widget.js"></script>
<script src="jquery.js"></script>
<!--etc -->

Related

How to load error trackers from script tag?

I'm working on small .js which is going to be embedded on multiple websites, it will be loaded in a classic way - via script tag: <script src="myscript.js"></script> in sites body tag. I cannot add any more scripts to those sites.
I would like to track errors with error tracker such as Sentry, Rollup or HoneyBadger. However, all of them require being loaded with another script tag, most preferred before everything else.
Note: Those services need to load before everything else to catch errors property.
As I cannot add another script tag in the site's code, I need to execute their code inside my script, but before my actual script code.
I tried taking the content of HoneyBadger javascript library and putting it directly inside my file - it worked, however, I feel like it's terrible practice, as their code is written with modern browsers in mind, and mine supports older ones.
Is there any good way in my situation to load their .js externally?
I don't think that would work because of the way honeybadger.js v0.5 parses the script tag to get those attributes--it looks for the script tag in the dom when it's loaded.
Also, we've moved away from using the data- attributes in honeybadger.js v1.0, which was just released. In that version, you must use Honeybadger.configure to set your API key. Take a look at the new docs here:
https://docs.honeybadger.io/lib/javascript/integration/browser.html
I'd recommend going with v1.0, and using Honeybadger.configure for the configuration.

How to combine MVC bundling and asynchronous loading of JS files

I have an MVC page that has a number of JavaScript dependencies, let's call them depend-A and depend-B where depend-B depends on depend-A. These are both included in different bundles in MVC that is being included on the page. After running this through Google's pagespeed tool it suggested that we should be including the JS asynchronously to prevent render blocking.
Because of the dependencies, they need to load in particular order so I have looked into utilising LABJS to load them asynchronously in the correct order to prevent the render blocking.
This works by including the bundle's URL, but I lose the ability to be able to have the debug versions of the JS files locally while developing.
Can anyone suggest a way around this, so that we can load the JS files asynchronously but in order and maintain the debug versions locally?
Here is what I am currently using.
<script src="~/Scripts/LAB.min.js"></script>
<script>
$LAB
.script("#Scripts.Url("~/bundles/jquery")").wait()
.script("/scripts/fileone.js").wait()
.script("/scripts/filetwo.js").wait(function() {
FunctionInFileTwo();
});
</script>
The page source with the above code is as follows.
<script src="/Scripts/LAB.min.js"></script>
<script>
$LAB
.script("/bundles/jquery?v=GnU3whLS74nHNYUsUJjcWJKdXvKBNbFqBrkQVKSNlKc1").wait()
.script("/scripts/scripts/fileone.js").wait()
.script("/scripts/scripts/filetwo.js").wait(function() {
FunctionInFileTwo();
});
</script>
It doesn't look like there's any clean API available for this.
Scripts.Render("~/bundles/yourbundle") returns an IHtmlString of the necessary script tags - you could make a method that scavenges the script srcs from that string and generates the correct $LAB invocations.
Scripts.Manager.RenderExplicit(tagFormat, paths) comes close, where you'd just pass a better format string as the first argument, but reading the code it looks like it could start including differently formatted script tags verbatim in the middle of the list.

JavaScript file dependend on JavaScript code block in Yii2 (for dojo configuration)

I'm trying to register the dojo javascript files with Yii 2.0.
According to the dojo documentation, the code block for dojo config must be loaded before the actual dojo.js in order to be considered. However, in the HTML output my custom javascript code is always loaded after dojo.js.
This is my code:
$this->registerJs('dojoConfig="async:true,isDebug:true";', $this::POS_HEAD,'dojoconfiguration');
$this->registerJsFile('/dojo_toolkit/dojo/dojo.js', ['depends' => [\yii\web\JqueryAsset::className()], 'position' => yii\web\View::POS_HEAD]);
And in HTML it looks like this:
<script src="/dojo_toolkit/dojo/dojo.js"></script>
<script type="text/javascript">dojoConfig="async:true,isDebug:true";</script>
Any advise?
For the same position Yii2 always puts the inline scripts first and then the actual external files. So you can't fix this by adding them both to the <head>.
Its best to give the registerJsFile() call a POS_END to load it at the very end. It will still be loaded before the document.ready() call is made.
That way you can be sure that the configuration in the header is parsed before the load. Worst case scenario you can use POS_BEGIN to load it right after the body tag is opened, but since loading javascript is blocking I would try to avoid that.

Using jQuery to send a variable to an external script and grab the results

I have a basic webpage set up and I would like to use jQuery to send a single variable (user-generated) to a javascript script (external -- well not really, still on the server, just not embedded in the webpage). This script will do a bunch of stuff with the variable and spit out a large array of results. I then need to update my page with the results.
I've done something similar using AJAX to POST stuff to a PHP script, but how can this be done with a JS script?
well ... including your script using the following (as opposed to embedding it) will keep your source neat and clean:
<script src="yourscript.js" type="text/javascript"></script>
The file could contain a function which you then call from outside (ie, the actual page source). As JavaScript is executed on the client-side (ie, the browser), downloading the file is unavoidable (unless you take extreme measures like an apache::mod_js, or rewrite the function in PHP). Best to keep things simple and use the above.
<script type="text/javascript" src="path/javascript_file.js"></script>
I think this is more what Kaustubh means. You do not have to put the actual code blocks into the page, just reference it this way.
When the page loads it will also load the javascript file (clean)
you can then call the functions seamlessly.

jQuery 1.4 ajax callback, html() stripping external JS from response

Using jQuery 1.4 I've come across an issue with external JS in an ajax response being removed when accessing it using html().
I'm creating an endless scrolling effect for a tumblr theme using an ajax request to load the next page. Tumblr outputs JS in audio and slideshow posts to render <embed> elements (Flash players) to show the content. The markup cannot be changed.
Everything works fine using jQuery 1.3.2, the external JS is executed and renders the players, however in 1.4 the javascript is removed and I'm left with the fallback text. The JS is included in the response, but when using html() within the ajax callback I can't retrieve or get the javascript to execute.
I want to use jQuery 1.4 because I'm using some of it's new features in other parts, I can get it to work using split but I'm not sure how reliable it is to split the response on a specific string.
I've prepared a basic sample (includes 2 files, test.html & request.html) demonstrating the issue. Open test.html to load a local request from request.html
Is this behaviour deliberate, can I get around it, or am I just doing it wrong?
From the jQuery docs on .ajax():
If html is specified, any embedded
JavaScript inside the retrieved data
is executed before the HTML is
returned as a string. Similarly,
script will execute the JavaScript
that is pulled back from the server,
then return the script itself as
textual data.
I'm not finding any way around it... But it seems to be behaving different from 1.3.2 and the "1.3-compat" plugin doesn't seem to fix it either.
This looks like a bug in 1.4 to me—I get the same results using your sample code; switching back to 1.3.2 allows the embedded scripts to execute again.
The documentation certainly doesn't mention anything about any changes in 1.4 which prevent the execution of scripts in retrieved HTML. I'd post a question at the jQuery forum and see if anyone else is having the problem; you might get the attention of one of the jQuery devs too.

Categories