XMLHttpRequest returns response before page is fully loaded

时间:2015-10-06 08:27:29

标签: javascript ajax

I'm trying to automate the search function at https://developers.arcgis.com/javascript/jssamples/#search/ using XMLHttpRequest, but the response is coming back before the results have loaded.

If you put a search term like Layer, Geoprocessor, Legend, etc. on the end of the url above and load the page, the #sample-thumbs div will contain links to samples that contain the search term. It takes about 10 seconds to load though, and the request returns before that, so the #sample-thumbs div is not yet present and the #samplesLoading div is still visible.

Here is my request function; I am checking that readyState is 4 and status is 200 before returning the response, so XMLHttpRequest thinks the page is fully loaded. The page is mostly complete, apart from the results div, which takes a further few seconds to load.

function doAjaxRequest (requestUrl, callback) {
    var ajaxRequest;

    // Create a request Object
    ajaxRequest = new XMLHttpRequest();
    ajaxRequest.onreadystatechange = function () {
        if (ajaxRequest.readyState == 4) {
            if (ajaxRequest.status == 200) {
                callback(ajaxRequest.response);
            }
        }
    };
    // Set response type
    ajaxRequest.responseType = "document";
    // Open url
    ajaxRequest.open("GET", requestUrl, true);
    // Send request
    ajaxRequest.send(null);
}

So, the question is, can I make XMLHttpRequest wait until #sample-thumbs has appeared? Or can I make a second request (or multiple requests) to the same page to check if this div has appeared yet? It seems like the XMLHttpResponse is just returning a snapshot, so should I be using another method to get a dynamic response, which will continue to update as the page loads?

Sorry, that's actually three questions. Basically I'm asking if what I'm trying to do is possible with XMLHttpRequest, and if not, what else could I use?

UPDATE: Here's a full snippet. If you set a breakpoint at line 25 (.innerHTML += ...) and watch ajaxRequest.responseXML.querySelectorAll("#samplesLoading"), you can see the loading div is there. The #sample-thumbs div is not.

function doAjaxRequest(requestUrl) {
  var ajaxRequest, loadingDiv;

  // Create a request Object
  ajaxRequest = new XMLHttpRequest();
  ajaxRequest.onreadystatechange = function() {
    if (ajaxRequest.readyState == 4) {
      if (ajaxRequest.status == 200) {
        document.getElementById("output").innerHTML += ajaxRequest.response.querySelectorAll("#sample-thumbs ul");
      }
    }
  };
  // Set response type
  ajaxRequest.responseType = "document";
  // Open url
  ajaxRequest.open("GET", requestUrl, true);
  // Send request
  ajaxRequest.send(null);
};

function doSearch() {
  var requestUrl;

  // build query url
  requestUrl = "https://developers.arcgis.com/javascript/jssamples/#search/";
  doAjaxRequest(requestUrl + document.getElementById("searchTerm1").value);
};
<div id="bcMain">
  <div id="cpRequest">
    <h2>Request test</h2>
    <label for="searchTerm1">Search Term 1</label>
    <input id="searchTerm1" type="text"/>
    <br><br>
    <button id="btnHttpRequest" type="button" onclick="doSearch()">Search</button>
  </div>
  <div id="cpResults">
    <h2>Results</h2>
    <div id="output"></div>
  </div>
</div>

1 个答案:

答案 0 :(得分:0)

如果您在页面加载之前创建XMLHttpRequest,当然可能会在页面加载之前返回。

解决方案非常简单,等到DOM准备好后,然后发出请求。 ajaxRequest.readyState == 4仅检查AJAX请求是否准备就绪,它没有声明您的DOM树。

如果您需要在Web应用程序中不断更新数据,那么AJAX本身是不够的。传统上,这是通过类似Comet的解决方案,长轮询等解决的。但幸运的是,最近您可以使用WebSockets,这可以在Web应用程序中实现双向通信。