同步 XMLHttpRequest 已弃用

Synchronous XMLHttpRequest deprecated

今天,由于扩展程序出现问题,我不得不重新启动浏览器。当我重新启动它时,我发现我的浏览器 (Chromium) 自动更新到一个新版本,不再允许同步 AJAX-requests。引用:

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/.

我的 node.js 应用程序需要同步 AJAX 请求才能正常工作,因为它们通过使用 fopen 的服务器从磁盘存储和加载数据。我发现这是一种非常简单和有效的做事方式,在创建小爱好项目和编辑器时非常方便...有没有办法在 Chrome/Chromium 中重新启用同步 XMLHttpRequests?

此答案已被编辑。

简答: 他们不想在 main 线程上同步。

对于支持 threads/web worker 的新浏览器,解决方案很简单:

var foo = new Worker("scriptWithSyncRequests.js")

DOM 和全局变量都不会在 worker 中不可见,但封装多个同步请求将非常容易。

替代解决方案是切换到异步,但使用浏览器 localStorage 和 JSON.stringify 作为媒介。如果允许执行一些 IO,则可以模拟 localStorage。 http://caniuse.com/#search=localstorage

只是为了好玩,如果我们想只使用同步来限制我们的自我,还有其他黑客:

使用 setTimeout 很诱人,因为人们可能认为这是一种将同步请求封装在一起的好方法。可悲的是,有一个陷阱。 javascript 中的异步并不意味着它在自己的线程中到达 运行。 Async 很可能会推迟调用,等待其他人完成。对我们来说幸运的是,隧道尽头有光,因为您很可能可以使用 xhttp.timeout 和 xhttp.ontimeout 来恢复。参见 这意味着我们可以实现处理失败请求并分配时间重试或报告错误的调度程序的微型版本。

// 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);
}

"deprecated" 不是说它可用,但不会永远可用。 (我在其他地方读到它不会消失很多年。)如果是这样,这是针对业余爱好项目的,那么也许您现在可以使用 async: false 作为完成工作的快速方法?