3

I'm simply using an example from a book I'm reading. The example is labeled, "Loading HTML with Ajax." This is the JS portion of the code:

var xhr = new XMLHttpRequest();

xhr.onload = function() {
  if(xhr.status === 200) {
    document.getElementById('content').innerHTML = xhr.responseText;
  }
};

xhr.open('GET', 'data/data.html', true);
xhr.send(null);

I'm getting the CSS portion of the code (headers, etc.) when I load the page onto the browser but none of the JS (there should be maps which would load onto the page). The example says I should comment out this portion of the code above:

xhr.onload = function() {
  if(xhr.status === 200) {
    document.getElementById('content').innerHTML = xhr.responseText;

...if I'm running the code locally without a server but that's not working, either.

halfer
  • 19,824
  • 17
  • 99
  • 186
Andrew Rea
  • 138
  • 10
  • Do you really need to use XHR? `fetch` is better and less verbose in terms of code – Dominik Matis Jan 02 '20 at 18:41
  • That was the code provided by the example in the book I'm reading. Can you give an example of using `fetch`? – Andrew Rea Jan 02 '20 at 18:49
  • if a response is JSON format then `fetch(url).then(response => response.json()).then(data => document.getElementById('content').innerText = JSON.stringify(data))` – Dominik Matis Jan 02 '20 at 18:51
  • *But...* TJ's formal "answer," just below, probably hits the *actual* nail on the head. You're superficially asking about `XMLHttpRequest()` as being a way of sending an AJAX request, when the real issue in your case seems to have to do with JavaScript code. An entirely different concern which actually has nothing to do with exactly how the request is sent or received. See the Answer ... – Mike Robinson Jan 02 '20 at 18:55

2 Answers2

6

Is using XMLHttpRequest() an outdated way to make an Ajax call?

Yes, but it still works and that's not the problem. The more modern way is fetch.

I'm getting the CSS portion of the code (headers, etc.) when I load the page onto the browser but none of the JS (there should be maps which would load onto the page).

That's because assigning HTML that contains script tags to innerHTML doesn't run the script defined by those tags. The script tags are effectively ignored.

To run those scripts, you'll need to find them in the result and then recreate them, something along these lines:

var content = document.getElementById('content');
content.innerHTML = xhr.responseText;
content.querySelectorAll("script").forEach(function(script) {
    var newScript = document.createElement("script");
    newScript.type = script.type;
    if (script.src) {
        newScript.src = script.src;
    } else {
        newScript.textContent = script.textContent;
    }
    document.body.appendChild(newScript);
});

Note that this is not the same as loading the page with script elements in it directly. The code within script tags without async or defer or type="module" is executed immediately when the closing script tag is encountered when loading a page directly (so that the loaded script can use document.write to output to the HTML stream; this is very mid 1990s). Whereas in the above, they're run afterward.

Note that on older browsers, querySelectorAll's NodeList may not have forEach, that was added just a few years ago. See my answer here if you need to polyfill it.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks, T.J. I haven't tried your solution yet. Before I read your answer, I was trying something I read on [mozilla]:(developer.mozilla.org): `function reqListener() { console.log(this.responseText); } var xhr = new XMLHttpRequest(); xhr.addEventListener("load", reqListener); xhr.open("GET", "data/data.html"); xhr.send();` But I got this error message in the Console: – Andrew Rea Jan 02 '20 at 19:09
  • `Access to XMLHttpRequest at 'file:///Users/andrewrea/Downloads/javascript-and-jquery-book-code-0915/c08/data/data.html' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.` – Andrew Rea Jan 02 '20 at 19:11
  • @AndrewRea - Yes, in most browsers you can only use ajax (whether `XMLHttpRequest` or `fetch`) from pages served over HTTP or HTTPS, not local files loaded with the `file:` pseudo-scheme. In general, with web technologies, you want to run a local server rather than loading files directly. Ajax isn't the only thing that doesn't work for pages loaded over `file:` URIs, several other things either don't work or work *slightly differently* for pages loaded via `file:` URIs. Best to stick to HTTP/HTTPS. – T.J. Crowder Jan 02 '20 at 19:24
0

Because I didn't completely understand T.J.'s answer (no offense, T.J.), I wanted to provide a simple answer for anyone who might be reading this. I only recently found this answer on Mozilla.org: How do you set up a local testing server? (https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server). I won't go into details, I'll just leave the answer up to Mozilla. (Scroll down the page to the section titled, "Running a simple local HTTP server.")

Andrew Rea
  • 138
  • 10