gpt4 book ai didi

javascript - 如何控制 HTML5 Web Worker 上的 XMLHttpRequest 对象?

转载 作者:行者123 更新时间:2023-11-30 11:11:36 25 4
gpt4 key购买 nike

我有一个页面通常会使用一个包装器覆盖 window.XMLHttpRequest,该包装器会做一些额外的事情,比如在某些请求的 header 中插入。

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

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

这个第 3 方库代码如下所示:

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

上面的 URL 变量返回的 Javascript 包含如下代码:

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

最佳答案

答案既是温和的“否”,也是最终的"is"。

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

此外,XMLHttpRequest 并不是发送网络请求的唯一方法——您还有其他几种方法,其中最主要的是fetch api。 .

但是,有一个相对较新的工具叫做 Service Worker,它可以为您提供很多帮助!

服务人员

Service workers (缩写。SWs)非常像你已经知道的网络 worker ,但不是只在当前页面运行,只要你的用户留在你的域中,它们就会继续在后台运行。它们对您的整个域都是全局的,因此从您的站点发出的任何请求都将通过它们传递。

它们的主要用途是响应网络请求,通常用于缓存目的和离线内容、提供推送通知以及其他一些小众用途。

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

// index.html
<script>
navigator.serviceWorker.register('sw.js')
.then(console.log.bind(console, 'SW registered!'))
.catch(console.error.bind(console, 'Oh nose!'));

setInterval(() => {
fetch('/hello/');
}, 5000);
</script>

// sw.js
console.log('Hello from a friendly service worker');

addEventListener('fetch', event => {
console.log('fetch!', event);
})

在这里,我们注册了一个 service worker,然后每 5 秒请求一个页面。在 service worker 中,我们简单地记录每个网络事件,这些事件可以在 fetch 事件中捕获。

在第一次加载时,您应该会看到正在注册的服务 worker 。 SWs 仅在安装它们之后 才开始拦截来自第一页的请求...因此刷新页面以开始查看正在记录的 fetch 事件。我建议您在继续阅读之前先了解一下事件属性,这样事情会更清楚。

太棒了!我们可以通过查看控制台中的事件看到 event.requestRequest。对象我们的浏览器构建。在理想情况下,我们可以访问 event.request.headers 并添加我们自己的 header !很梦幻,不是吗!?

不幸的是,request/response headers are guarded and immutable .幸运的是,我们是一群固执的人,可以简单地重新构造请求:

// sw.js
console.log('Hello from a friendly service worker');

addEventListener('fetch', event => {
console.log('fetch!', event);
// extract our request
const { request } = event;

// clone the current headers
const newHeaders = new Headers();
for (const [key, val] of request.headers) {
newHeaders.append(key, val);
}
// ...and add one of our own
newHeaders.append('Say-What', 'You heard me!');

// clone the request, but override the headers with our own
const superDuperReq = new Request(request, {
headers: newHeaders
});

// now instead of the original request, our new request will take precedence!
return fetch(superDuperReq);
});

这是几个不同的概念在起作用,所以如果需要多次获得也没有关系。但本质上,我们正在创建一个新的请求来代替原来的请求,并设置一个新的 header !欢呼!

enter image description here

坏事

现在,对于一些缺点:

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

(1) 您可以在 same origin 中访问 iframe 的全局对象和您一样,但是让您的代码首先运行以修改全局对象确实很棘手。

关于javascript - 如何控制 HTML5 Web Worker 上的 XMLHttpRequest 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53401528/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com