如何强制程序在 JavaScript 中等待 HTTP 请求完成?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3760319/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to force a program to wait until an HTTP request is finished in JavaScript?
提问by Thanasis Petsas
Is there a way in JavaScript to send an HTTP request to an HTTP server and wait until the server responds with a reply? I want my program to wait until the server replies and not to execute any other command that is after this request. If the HTTP server is down I want the HTTP request to be repeated after a timeout until the server replies, and then the execution of the program can continue normally.
JavaScript 中有没有办法将 HTTP 请求发送到 HTTP 服务器并等待服务器响应回复?我希望我的程序等到服务器回复并且不执行此请求之后的任何其他命令。如果HTTP服务器宕机,我希望超时后重复HTTP请求,直到服务器回复,然后程序的执行才能正常继续。
Any ideas?
有任何想法吗?
Thank you in advance, Thanasis
提前谢谢你,塔纳西斯
回答by Javarome
There is a 3rd parameter to XmlHttpRequest's open(), which aims to indicate that you want the request to by asynchronous (and so handle the response through an onreadystatechangehandler).
XmlHttpRequest's有第三个参数open(),它旨在表明您希望通过异步请求(因此通过onreadystatechange处理程序处理响应)。
So if you want it to be synchronous (i.e. wait for the answer), just specify false for this 3rd argument.
You may also want to set a limited timeoutproperty for your request in this case, as it would block the page until reception.
因此,如果您希望它是同步的(即等待答案),只需为此第三个参数指定 false。timeout在这种情况下,您可能还想为您的请求设置一个有限的属性,因为它会阻止页面直到接收为止。
Here is an all-in-one sample function for both sync and async:
这是同步和异步的多合一示例函数:
function httpRequest(address, reqType, asyncProc) {
var req = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
if (asyncProc) {
req.onreadystatechange = function() {
if (this.readyState == 4) {
asyncProc(this);
}
};
} else {
req.timeout = 4000; // Reduce default 2mn-like timeout to 4 s if synchronous
}
req.open(reqType, address, !(!asyncProc));
req.send();
return req;
}
which you could call this way:
你可以这样称呼它:
var req = httpRequest("http://example.com/aPageToTestForExistence.html", "HEAD"); // In this example you don't want to GET the full page contents
alert(req.status == 200 ? "found!" : "failed"); // We didn't provided an async proc so this will be executed after request completion only
回答by jwueller
You can perform a synchronous request. jQuery example:
您可以执行同步请求。jQuery 示例:
$(function() {
$.ajax({
async: false,
// other parameters
});
});
You should take a look at jQuery's AJAX API. I highly recommend using a framework like jQuery for this stuff. Manually doing cross-browser ajax is a real pain!
你应该看看 jQuery's AJAX API。我强烈建议使用像 jQuery 这样的框架来处理这些东西。手动做跨浏览器ajax真的很痛苦!
回答by Ashif Nataliya
You can use XMLHttpRequest object to send your request. Once request is sent, you can check readyState property to identify current state. readyState will have following different states.
您可以使用 XMLHttpRequest 对象来发送您的请求。发送请求后,您可以检查 readyState 属性以识别当前状态。readyState 将有以下不同的状态。
- Uninitialized - Has not started loading yet
- Loading - Is loading
- Interactive - Has loaded enough and the user can interact with it
- Complete - Fully loaded
- 未初始化 - 尚未开始加载
- 正在加载 - 正在加载
- 交互式 - 已加载足够并且用户可以与之交互
- 完成 - 满载
for example:
例如:
xmlhttp.open("GET","somepage.xml",true);
xmlhttp.onreadystatechange = checkData;
xmlhttp.send(null);
function checkData()
{
alert(xmlhttp.readyState);
}
hope this will help
希望这会有所帮助
回答by Argenti Apparatus
I have a similar situation in an game built with Three.js and Google Closure. I have to load 2 resources, Three and Closure do not allow me to make these synchronous.
我在用 Three.js 和 Google Closure 构建的游戏中遇到了类似的情况。我必须加载 2 个资源,三个和 Closure 不允许我使这些同步。
Initially I naively wrote the following:
最初我天真地写了以下内容:
main() {
...
var loaded=0;
...
// Load Three geometry
var loader = new THREE.JSONLoader();
loader.load("x/data.three.json", function(geometry) {
...
loaded++;
});
// Load my engine data
goog.net.XhrIo.send("x/data.engine.json", function(e) {
var obj = e.target.getResponseJson();
...
loaded++;
});
// Wait for callbacks to complete
while(loaded<2) {}
// Initiate an animation loop
...
};
The loop that waits for the callbacks to complete never ends, from the point of view of the loop loadednever get incremented. The problem is that the callbacks are not fired until mainreturns (at least on Chrome anyway).
等待回调完成的循环loaded永远不会结束,从循环的角度来看,永远不会增加。问题是回调在main返回之前不会被触发(至少在 Chrome 上是这样)。
One solution might be to have both callbacks check to see if it's the last to complete, and them go on to initiate the animation loop.
一种解决方案可能是让两个回调都检查它是否是最后一个完成的,然后它们继续启动动画循环。
Another solution - perhaps a more direct answer to what you are asking (how to wait for each load before initiating another) - would be to nest the callbacks as follows:
另一个解决方案 - 也许是对您所问的更直接的回答(如何在启动另一个之前等待每个负载) - 将按如下方式嵌套回调:
// Load Three geometry
var loader = new THREE.JSONLoader();
loader.load("x/data.three.json", function(geometry) {
...
// Load my engine data
goog.net.XhrIo.send("x/data.engine.json", function(e) {
var obj = e.target.getResponseJson();
...
// Initiate an animation loop
...
});
});
};
回答by Nik
For this you can start loader in javascript as soon as page starts loading and then you can close it when request finishes or your dom is ready. What i am trying to say, as page load starts, start a loader . Then page can do multiple synchronous request using ajax , until and unless you didn't get response, do not close close loader. After receiving the desired in response in final call, you can close the loader.
为此,您可以在页面开始加载后立即在 javascript 中启动加载器,然后在请求完成或 dom 准备就绪时关闭它。我想说的是,当页面加载开始时,启动一个 loader 。然后页面可以使用 ajax 执行多个同步请求,直到并且除非您没有得到响应,否则不要关闭关闭加载器。在最终调用中收到所需的响应后,您可以关闭加载程序。

