Relative URL does not get resolved correctly by jQ

2019-04-10 22:22发布

问题:

I am building a Rails (3.0.3) application with some JavaScript using jQuery (1.4.4). On one of the sites I added a click event listener and want to load some content using a AJAX request.

$(document).ready(function() {
  $("a#settings").click(function() {
    $("div#box").load("settings.js");
    return false;
  });
});

When I now open the site "http://localhost:3000/entities/3" where the link with the bound click listener is located and click the link I get a 404 error. This happens because the AJAX request uses the URL "http://localhost:3000/entities/settings.js" and not (as I would exect) "http://localhost:3000/entities/3/settings.js".

回答1:

There is an answer by some of a very similar but library independent question:

This is how relative paths is supposed to work.

protocol://some.domain.name/dir1/dir2/filename

If you specify only a new filename "foo", you get the same protocol, host and dirs, only the file name is changed:

protocol://some.domain.name/dir1/dir2/foo

If you specify a whole path "/dir3/filename2" you get the same protocol and hostname but with another path:

protocol://some.domain.name/dir3/filename2

You can also specify host name "//another.domain.name/dir5/filename3" and get the same protocol but another host, dir and filename:

protocol://another.domain.name/dir5/filename3

What might be confusing is that a webserver internally can add a / at the end of the url if the specified url points to a directory and not to a file.

protocol://some.domain.name/somename

If "somename" is a directory the webserver translates it to

protocol://some.domain.name/somename/

For reference, see step 6 in section 4 of RFC 1808



回答2:

Looking through the jQuery source for $.fn.load and subsequently $.ajax, I can't find anything that tries to account for relative paths. It does extract pieces of information from absolute paths, but that's only to test for remoteness. That being said, try the following and see if the result is any different, because I may have missed something:

$(document).ready(function() {
    $("#settings").click(function() {
        var xhr = new XMLHttpRequest();
        xhr.open("GET", "settings.js", true);
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                $('#box').html(xhr.responseText);
            }
        };
        xhr.send(null);
        return false;
    });
});

My guess is that this may be a browser-specific issue.