不推荐使用同步 XMLHttpRequest
今天,由于扩展程序的一些问题,我不得不重新启动浏览器.当我重新启动它时,我发现我的浏览器(Chromium)自动更新到不再允许同步 AJAX 请求的新版本.引用:
Today, I had to restart my browser due to some issue with an extension. What I found when I restarted it, was that my browser (Chromium) automatically updated to a new version that doesn't allow synchronous AJAX-requests anymore. Quote:
主线程上的同步 XMLHttpRequest 已被弃用,因为其对最终用户体验的不利影响.如需更多帮助,检查 http://xhr.spec.whatwg.org/.
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.
我需要同步 AJAX 请求才能让我的 node.js 应用程序工作,因为它们通过使用 fopen 的服务器从磁盘存储和加载数据.我发现这是一种非常简单有效的做事方式,在创建小爱好项目和编辑器时非常方便......有没有办法在 Chrome/Chromium 中重新启用同步 XMLHttpRequests?
I need synchronous AJAX-requests for my node.js applications to work though, as they store and load data from disk through a server utilizing fopen. I found this to be a very simplistic and effective way of doing things, very handy in the creation of little hobby projects and editors... Is there a way to re-enable synchronous XMLHttpRequests in Chrome/Chromium?
推荐答案
此答案已编辑.
简答:他们不想在 main 线程上同步.
Short answer: They don't want sync on the main thread.
对于支持线程/网络工作者的新浏览器来说,解决方案很简单:
The solution is simple for new browsers that support threads/web workers:
var foo = new Worker("scriptWithSyncRequests.js")
DOM 和全局变量都不会在 worker 中可见,但封装多个同步请求将非常容易.
Neither DOM nor global vairables aren't going to be visible within a worker but encapsulation of multiple synchronous requests is going to be really easy.
替代解决方案是切换到异步,但使用浏览器 localStorage 和 JSON.stringify 作为媒介.如果你允许做一些 IO,你也许可以模拟 localStorage.http://caniuse.com/#search=localstorage
Alternative solution is to switch to async but to use browser localStorage along with JSON.stringify as a medium. You might be able to mock localStorage if you allowed to do some IO. http://caniuse.com/#search=localstorage
只是为了好玩,如果我们想限制自己只使用同步,还有其他的技巧:
Just for fun, there are alternative hacks if we want to restrict our self using only sync:
使用 setTimeout 很诱人,因为人们可能认为它是一种将同步请求封装在一起的好方法.可悲的是,有一个问题.javascript 中的异步并不意味着它可以在自己的线程中运行.Async 可能会推迟调用,等待其他人完成.幸运的是,隧道尽头有光,因为您很可能可以使用 xhttp.timeout 和 xhttp.ontimeout 来恢复.请参阅 超时 XMLHttpRequest这意味着我们可以实现微型版本的调度程序来处理失败的请求并分配时间重试或报告错误.
It is tempting to use setTimeout because one might think it is a good way to encapsulate synchronous requests together. Sadly, there is a gotcha. Async in javascript doesn't mean it gets to run in its own thread. Async is likely postponing the call, waiting for others to finish. Lucky for us there is light at the end of the tunnel because it is likely you can use xhttp.timeout along with xhttp.ontimeout to recover. See Timeout XMLHttpRequest This means we can implement tiny version of a schedular that handles failed request and allocates time to try again or report error.
// The basic idea.
function runSchedular(s)
{
setTimeout(function() {
if (s.ptr < callQueue.length) {
// Handles rescheduling if needed by pushing the que.
// Remember to set time for xhttp.timeout.
// Use xhttp.ontimeout to set default return value for failure.
// The pushed function might do something like: (in pesudo)
// if !d1
// d1 = get(http...?query);
// if !d2
// d2 = get(http...?query);
// if (!d1) {pushQue tryAgainLater}
// if (!d2) {pushQue tryAgainLater}
// if (d1 && d2) {pushQue handleData}
s = s.callQueue[s.ptr++](s);
} else {
// Clear the que when there is nothing more to do.
s.ptr = 0;
s.callQueue = [];
// You could implement an idle counter and increase this value to free
// CPU time.
s.t = 200;
}
runSchedular(s);
}, s.t);
}
相关文章