skip to Main Content

In an HTML file, are the following two script includes functionally equivalent?

index.html

  <script src="file.js"></script>

and

  <script src="./file.js"></script>

From what I remember, when files are resolved:

(1) The current directory of the HTML file is used by default for resolving relative paths,

(2) So "file.js" and "./file.js" are resolved using the path/directory of the HTML file.

When I experiment with this, they work the same in my test browser/server, but when it’s behind an nginx load balancer with a route it is failing. But I think this is a different issue which would be an entirely different question.

EDIT: The value of the PATH environment variable and the rules for executable files lookup are unrelated to the way that HTML <script src="file.js"> is handled.

2

Answers


  1. Chosen as BEST ANSWER

    While the MDN docs for script are not helpful, this article http://brianvanderplaats.com/2017/01/16/understanding-relative-urls/ covers the issue and explains how relative paths are handled.

    How it works

    The way a script is handled is not determined by the server but is instead determined by the browser. The browser parses the element and makes an HTTP GET request to ask for the javascript file.

    For example, if the following browser page were opened http://host.com/app/dir1/index.html and the following script element was found:

        <script src="file.js"></script>
    

    When examined in Chrome's devtools I see that an HTTP GET for the file being sent to the server.

    http://host.com/app/dir1/file.js
    

    What the standard says

    The HTML standard in 4.3.1 The script element says:

    If the element has a src attribute, then the value of that attribute must be resolved relative to the element, and if that is successful, the specified resource must then be fetched, from the origin of the element's Document.

    This means relative to the index.html file and then requested via the document's origin which is document.location.origin. NOTE: Technically, the element refers to DOM element but I'm keeping it simple.

    If we change the index.html file to include a dot, then we see the same HTML GET is issued. So this:

        <script src="./file.js"></script>
    

    Also results to the same HTTP GET being issued:

    http://host.com/app/dir1/file.js
    

    Hopefully this clearly that src="file.js" is functionally the same as src="./file.js".

    Current is changed when <base> element is used

    It is worth noting that if the <base> element exists, then it will be used instead of the current location. For example,

    <html>
      <head>
        <base href="https://just-a-test/dir1/">
        <script src="./file33.js"></script>
      </head>
      <body>... rest not shown
    

    Then the browser will issue an HTTP GET for

    https://just-a-test/dir1/file33.js
    

    Another interesting case is when a relative path uses a sub-directory, or dot-dot syntax to get to a parent directory ../images/img1.png.

    In both cases, the browser resolves the name and issues and HTTP GET Request for the resource it believes is the correct name. So

    <html>
      <head>
        <base href="https://just-a-test/dir1/">
      </head>
      <body>
        <img src="../images/img1.png"></script>
      </body>
    </html>
    

    results in an HTTP GET request to the following file.

     https://just-a-test.com/images/img1.png
    

    <base> can include filename

    Lastly, the <base> element can include a filename such as:

    <html>
      <head>
        <base href="https://just-a-test/dir1/index.html">
      </head>
      <body>
        <img src="img44.png"></script>
      </body>
    </html>
    

    When this happens, the filename is dropped and only the remaining path is used so in this case an HTTP GET request is made for this file.

     https://just-a-test.com/dir1/img44.png
    

    And not the file https://just-a-test.com/dir1/index.html/img44.png.

    I bring this case up because a common bug is to leave off the trailing slash and wonder why things are not working. For example,

    <html>
      <head>
        <base href="https://just-a-test/dir1">
      </head>
      <body>
        <img src="img44.png"></script>
      </body>
    </html>
    

    Results in an HTTP GET Request to

    https://just-a-test.com/img44.png
    

    Which might make you think it wasn't working. This happens because dir1 is viewed just like index.html in the previous example and ignored for the purposes of issuing the HTTP GET requests.

    Documentation on <base>

    The MDN documentation for base is here and the HTML5 standard for <base> is here. My hightlights are:

    • If the document has no elements, then the browser uses location.href. A base can include a filename.

    • If multiple elements are used, only the first href and first target are obeyed — all others are ignored.

    • A base element must have either an href attribute, a target attribute, or both.

    • The base element has to be put in the <head> element.

    • The base element does not have a closing tag.


  2. There is no difference between the two from web browser perspective.

    However, on *nix systems, for example in shell, file.js would be searched in $PATH, while ./file.js will be searched in current directory.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search