XMLHttp request vs "html tag" resource loading

I'm currently building a little SPA framework of my own. I'm just curious, how does some things work in a background.

Let's say, I want to dynamically import a script from the server.

The method that I'm currently using is including a script tag to the head, with "async" attribute set to true. Something like this.

for (let requiredScript of requiredScripts){
  var $head = document.getElementsByTagName('head')[0];
  var $script = document.createElement('script');
  $script.src = requiredScript;
  $script.async = true;
  $script.onload = function(){
    callback();
  }

  $head.appendChild($script);
}

How does this work exactly in browsers? I read that browsers spawn a new thread for every script in the head tag, and when they load, they exacute them. (I could also use defer attribute, but it doesnt matter there).

This (if it works as I expect it to work), is great. Syntax is ugly, but it works. With a little disadvantage: I can't explicitly set the header for those requests. For example, I want to add a JWT token to every request for restricted resource, which I can't, and I have to use ajax call. But this is not a part of this question.

So, second way to load my resources (there's a third way, ES6 import, but I'm not gonna use this for now) is to load my resources via an AJAX call. But from the nature of XMLHttp request, I get only a string, or maybe JSON, but not a script, so I have to call eval(), which is both slow and insecure.

But let's get to the question. What exactly is a resource call in a script tag? How does it differ from xmlhttp request (or an ajax call)? What exactly does browser do, when parsing html file and evaluating the line with script tag? Can I import a javascript file as a binary file, and make browser just execute it? (faster and safer option that eval()). I want to have full control and understanding behind what I'm doing, but I feel very confused and can't find the right answers on this topic.

Every explanation (or even a helpful link) would be much appretiated.

Upvotes: 0

Views: 228

Answers (1)

jfriend00
jfriend00

Reputation: 708146

What exactly is a resource call in a script tag?

A <script> tag just tells the browser to do an http GET on the URL in the script tag and then send the resulting text to the Javascript interpreter to be parsed and run. You can watch the network tab in the browser debugger to see the exact http GET operation that it is doing.

How does it differ from xmlhttp request (or an ajax call)?

The initial request in both is an http GET so that doesn't differ at all. An xmlhttp request is subject to same-origin security protections. A <script> tag is not subject to same-origin protections so it can load a script from anywhere.

What exactly does browser do, when parsing html file and evaluating the line with script tag?

I think this is described above (an http GET, then result passed to the JS parser).

Can I import a javascript file as a binary file, and make browser just execute it? (faster and safer option that eval())

No, not really. First off, a JS file is not binary, it's text. There is not yet an adopted and widely implemented standard for pre-parsed/compiled binary Javascript. You can read about Emscripten and Asm.js to see some of the work being done in this regard, though Emscripten really targets conversion of other language code into JS.

When you say "safer than eval()", you'd have to describe what problem you're trying to protect from. Either loading a script tag or loading the script with Ajax and then calling eval() on it is going to evaluate the script in the global context and going to have wide ranging capabilities to muck with your page.

You can control the loading and execution yourself (if not a cross-origin request) by using an XMLHttpRequest to retrieve the script text and then you can parse and execute it yourself either by inserting the text into a script tag or by calling eval() on it. Unless you want to modify or verify the script in some way before executing it, there is really no benefit to manually loading it yourself.

Upvotes: 1

Related Questions