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
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:When examined in Chrome's devtools I see that an HTTP GET for the file being sent to the server.
What the standard says
The HTML standard in 4.3.1 The script element says:
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:
Also results to the same HTTP GET being issued:
Hopefully this clearly that
src="file.js"
is functionally the same assrc="./file.js"
.Current is changed when
<base>
element is usedIt is worth noting that if the
<base>
element exists, then it will be used instead of the current location. For example,Then the browser will issue an HTTP GET for
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
results in an HTTP GET request to the following file.
<base>
can include filenameLastly, the
<base>
element can include a filename such as: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.
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,
Results in an HTTP GET Request to
Which might make you think it wasn't working. This happens because
Documentation ondir1
is viewed just likeindex.html
in the previous example and ignored for the purposes of issuing the HTTP GET requests.<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.
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.