Javascript 如何控制HTML5Web工作者上的XMLHttpRequest对象?

Javascript 如何控制HTML5Web工作者上的XMLHttpRequest对象?,javascript,web-worker,Javascript,Web Worker,我有一个页面,它通常会用一个包装器覆盖window.XMLHttpRequest,这个包装器会做一些额外的事情,比如在某些请求上插入标题 我在使用HTML5 Worker的第三方库中有一些功能,我们看到这个请求没有使用XMLHttpRequest包装器对象。因此,该库发出的任何请求都缺少所需的头,因此请求将失败 有没有办法控制当前线程创建的任何工作线程的XMLHttpRequest 此第三方库代码如下所示: function createWorker(url) {

我有一个页面,它通常会用一个包装器覆盖window.XMLHttpRequest,这个包装器会做一些额外的事情,比如在某些请求上插入标题

我在使用HTML5 Worker的第三方库中有一些功能,我们看到这个请求没有使用XMLHttpRequest包装器对象。因此,该库发出的任何请求都缺少所需的头,因此请求将失败

有没有办法控制当前线程创建的任何工作线程的XMLHttpRequest

此第三方库代码如下所示:

        function createWorker(url) {
            var worker = new Worker(url);
            worker.onmessage = function (e) {
                if (e.data.status) {
                    onprogress(e.data.status);
                } else if (e.data.error) {
                    onerror(e.data.error);
                } else {
                    exportUtils.saveFile(new Blob([e.data]), params.fileName);
                    onfinish();
                }
            };
            worker.postMessage(params); // window.location.origin +
            return worker;
        }
        return new Promise(function(t, r) {
            var n = new XMLHttpRequest
              , a = "batch_" + o()
              , u = e.dataUrl.split(e.serviceUrl)[1]
              , c = [];
            n.onload = function() {
                for (var e = this.responseText, n = this.responseText.split("\r\n"), o = 0, a = n.length, i = a - 1; o < a && "{" !== n[o].slice(0, 1); )
                    o++;
                for (; i > 0 && "}" !== n[i].slice(-1); )
                    i--;
                n = n.slice(o, i + 1),
                e = n.join("\r\n");
                try {
                    var u = JSON.parse(e);
                    t(u)
                } catch (t) {
                    r(s + e)
                }
            }
            ,
            n.onerror = function() {
                r(i)
            }
            ,
            n.onabort = function() {
                r(i)
            }
            ,
            n.open("POST", e.serviceUrl + "$batch", !0),
            n.setRequestHeader("Accept", "multipart/mixed"),
            n.setRequestHeader("Content-Type", "multipart/mixed;boundary=" + a);
            for (var p in e.headers)
                "accept" != p.toLowerCase() && n.setRequestHeader(p, e.headers[p]);
            c.push("--" + a),
            c.push("Content-Type: application/http"),
            c.push("Content-Transfer-Encoding: binary"),
            c.push(""),
            c.push("GET " + u + " HTTP/1.1");
            for (var p in e.headers)
                c.push(p + ":" + e.headers[p]);
            c.push(""),
            c.push(""),
            c.push("--" + a + "--"),
            c.push(""),
            c = c.join("\r\n"),
            n.send(c)
        }
        )
上面的URL变量返回的Javascript包含如下代码:

        function createWorker(url) {
            var worker = new Worker(url);
            worker.onmessage = function (e) {
                if (e.data.status) {
                    onprogress(e.data.status);
                } else if (e.data.error) {
                    onerror(e.data.error);
                } else {
                    exportUtils.saveFile(new Blob([e.data]), params.fileName);
                    onfinish();
                }
            };
            worker.postMessage(params); // window.location.origin +
            return worker;
        }
        return new Promise(function(t, r) {
            var n = new XMLHttpRequest
              , a = "batch_" + o()
              , u = e.dataUrl.split(e.serviceUrl)[1]
              , c = [];
            n.onload = function() {
                for (var e = this.responseText, n = this.responseText.split("\r\n"), o = 0, a = n.length, i = a - 1; o < a && "{" !== n[o].slice(0, 1); )
                    o++;
                for (; i > 0 && "}" !== n[i].slice(-1); )
                    i--;
                n = n.slice(o, i + 1),
                e = n.join("\r\n");
                try {
                    var u = JSON.parse(e);
                    t(u)
                } catch (t) {
                    r(s + e)
                }
            }
            ,
            n.onerror = function() {
                r(i)
            }
            ,
            n.onabort = function() {
                r(i)
            }
            ,
            n.open("POST", e.serviceUrl + "$batch", !0),
            n.setRequestHeader("Accept", "multipart/mixed"),
            n.setRequestHeader("Content-Type", "multipart/mixed;boundary=" + a);
            for (var p in e.headers)
                "accept" != p.toLowerCase() && n.setRequestHeader(p, e.headers[p]);
            c.push("--" + a),
            c.push("Content-Type: application/http"),
            c.push("Content-Transfer-Encoding: binary"),
            c.push(""),
            c.push("GET " + u + " HTTP/1.1");
            for (var p in e.headers)
                c.push(p + ":" + e.headers[p]);
            c.push(""),
            c.push(""),
            c.push("--" + a + "--"),
            c.push(""),
            c = c.join("\r\n"),
            n.send(c)
        }
        )
返回新承诺(函数(t,r){
var n=新的XMLHttpRequest
,a=“批处理”+o()
,u=e.dataUrl.split(e.serviceUrl)[1]
,c=[];
n、 onload=函数(){
对于(var e=this.responseText,n=this.responseText.split(“\r\n”),o=0,a=n.length,i=a-1;o0&&“}”!==n[i]。切片(-1);)
我--;
n=n.切片(o,i+1),
e=n.join(“\r\n”);
试一试{
var u=JSON.parse(e);
t(u)
}渔获物(t){
r(s+e)
}
}
,
n、 onerror=函数(){
r(i)
}
,
n、 onabort=函数(){
r(i)
}
,
n、 打开(“POST”,e.serviceUrl+“$batch”,!0),
n、 setRequestHeader(“接受”、“多部分/混合”),
n、 setRequestHeader(“内容类型”、“多部分/混合;边界=“+a”);
for(e.headers中的var p)
“accept”!=p.toLowerCase()&&n.setRequestHeader(p,e.headers[p]);
c、 推动(“-”+a),
c、 推送(“内容类型:应用程序/http”),
c、 推送(“内容传输编码:二进制”),
c、 推动(“”),
c、 推送(“获取”+u+“HTTP/1.1”);
for(e.headers中的var p)
c、 推送(p+”:“+e.headers[p]);
c、 推动(“”),
c、 推动(“”),
c、 按(“--”+a+“--”)键,
c、 推动(“”),
c=c.join(“\r\n”),
n、 发送(c)
}
)
答案是柔和的“不”和最终的“是”

当一段代码在不同的上下文(如webworker或iframe)中运行时,您无法直接控制其全局对象(1)

更重要的是,XMLHttpRequest不是发送网络请求的唯一方法——您还有其他几种方法,其中最主要的是

然而,在这个街区有一个相对较新的孩子叫服务工人,它可以帮你们很多忙

服务人员 (abbrev.SWs)与您已经知道的web工作者非常相似,但它们不只是在当前页面中运行,只要您的用户留在您的域中,它们就会继续在后台运行。它们对您的整个域也是全局的,因此从您的站点发出的任何请求都将通过它们传递

他们生活中的主要目的是对网络请求做出反应,通常用于缓存和离线内容,提供推送通知,以及其他一些特殊用途

让我们看一个小示例(注意,从本地Web服务器运行这些示例):

这是一些不同的概念在发挥作用,所以它是好的,如果它需要多次得到。基本上,我们正在创建一个新的请求,它将代替原来的请求发送,并设置一个新的头!万岁

坏的 现在,有一些不利因素:

  • 由于我们劫持了每一个请求,我们可能会意外地更改我们无意更改的请求,并可能破坏整个宇宙
  • 升级SWs是一个巨大的痛苦。软件生命周期很复杂,在用户上调试它很困难。我看过一段关于如何处理它的好视频,不幸的是现在找不到,但是
  • 调试SWs通常是一种非常烦人的体验,尤其是当与它们怪异的生命周期相结合时
  • 由于SWs功能强大,只能通过https提供服务。无论如何,您应该已经在使用https了,但这仍然是一个障碍
  • 这是为了一个相对较小的利益而做的很多事情,所以也许需要重新考虑它的必要性


(1) 您可以在as your中访问iframe的全局对象,但首先运行代码来修改全局对象确实很棘手。

这是您正在使用的服务人员还是普通的web人员?如果它是一个普通的web工作人员,那么实际上可以使用服务工作人员来处理所有传出的消息requests@Zirak我不知道“服务工作者”和“普通网络工作者”之间的区别,所以我在问题中发布了一些代码片段,这些代码片段应该能够澄清问题。我认为这是不可能的。在单独的全局上下文中运行。也就是说,如果您已经重写了
window.XMLHttpRequest
,那么工作人员将不会意识到这一点——它将使用自己的
XMLHttpRequest
获得自己的上下文。非常有趣的是,根据您的经验,服务工作人员使用此方法交换请求是否可以在所有支持“工作人员”的现代浏览器中工作?您可以在上看到支持率。基本上,都是非IE的,缺少Android 4的WebView支持。答案很棒。QQ:FetchAPI使用XMLHttpRequest,不是吗?