ZBLOG

let xhr = new XMLHttpRequest(); let conf; let path = ""; if (sdp_web_appid) { xhr.open('GET', path + '/sdpwebproxyconf' + '?GratuitousProxy=' + sdp_web_appid, false); } else { xhr.open('GET', path + '/sdpwebproxycon...

在 Web Worker 中执行同步 XMLHttpRequestxhr.open 的第三个参数为 false)会导致阻塞问题,因为 Worker 环境默认不允许同步 XHR(这是浏览器安全策略)。以下是解决方案和详细分析:


问题原因

  1. 同步 XHR 限制

    • 主线程中已废弃同步 XHR(因其会冻结 UI),但在 Worker 中原本是允许的。
    • 现代浏览器(Chrome/Firefox)默认禁止 Worker 中的同步 XHR,除非响应头包含 Require-Corp 或页面启用特殊标志(如 Chrome 的 --allow-sync-xhr-in-workers)。
  2. 卡住的表现

    • 调用 xhr.open(..., false) 时,Worker 线程会被阻塞,但浏览器未实际发送请求,导致后续代码无法执行。

解决方案

方法 1:改用异步 XHR(推荐)

let xhr = new XMLHttpRequest();
let conf;
let path = "";
const url = sdp_web_appid 
    ? `${path}/sdpwebproxyconf?GratuitousProxy=${sdp_web_appid}` 
    : `${path}/sdpwebproxyconf`;

xhr.open('GET', url, true); // 异步模式
xhr.onload = function() {
    if (xhr.status === 200) {
        conf = xhr.responseText;
        // 继续处理 conf
    } else {
        console.error("Failed to fetch webproxy conf:", xhr.status);
    }
};
xhr.onerror = function() {
    console.error("XHR request failed");
};
xhr.send();

方法 2:使用 fetch API(更现代)

const url = sdp_web_appid 
    ? `${path}/sdpwebproxyconf?GratuitousProxy=${sdp_web_appid}` 
    : `${path}/sdpwebproxyconf`;

fetch(url)
    .then(response => {
        if (!response.ok) throw new Error(`HTTP ${response.status}`);
        return response.text();
    })
    .then(conf => {
        // 处理 conf
    })
    .catch(err => console.error("Fetch failed:", err));

方法3:强制允许同步 XHR(不推荐)

如果必须用同步 XHR,需满足以下条件:

  1. 服务端设置响应头
    
    Cross-Origin-Opener-Policy: same-origin
    Cross-Origin-Embedder-Policy: require-corp
    
  2. 浏览器启动参数(仅开发环境):
    
    chrome --allow-sync-xhr-in-workers
    

关键注意事项

  1. Worker 中的全局对象差异
    • Web Worker 没有 window,但 XMLHttpRequest 仍可用。
  2. 路径问题
    • Worker 中的相对路径 (path) 是基于脚本所在位置,而非主页面 URL。
  3. 错误处理
    • Always handle onerror/.catch() to avoid silent failures.

总结

  • 优先改用异步请求(XHR async或Fetch API)。
  • ❌ Avoid sync XHR in Workers unless you control both server and client environments strictly.

示例代码已提供两种优化方案,根据实际需求选择即可。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=23237

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?