You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Safari 14中await request Promise失效,触发未处理Promise拒绝问题

解决Safari本地加载HTML文件的未处理Promise拒绝问题

问题根源

Safari处理file://协议的XMLHttpRequest请求时,成功加载本地文件后返回的xhr.status是0,而非Chrome中的200。你的request函数仅判断xhr.status >=200 && xhr.status <300时才resolve,导致Safari中直接进入reject分支,但调用代码未捕获该reject,触发了未处理Promise拒绝。

修复方案

1. 调整request函数的状态判断逻辑

修改xhr.onload中的判断条件,兼容本地文件请求的status=0情况:

function request (obj) {
    return new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest();
        xhr.open(obj.method || "GET", obj.url);
        if (obj.headers) {
            Object.keys(obj.headers).forEach(key => {
                xhr.setRequestHeader(key, obj.headers[key]);
            });
        }
        xhr.onload = () => {
            // 兼容file协议下的成功请求(status为0且有响应内容)
            if ((xhr.status >= 200 && xhr.status < 300) || (xhr.status === 0 && xhr.response)) {
                resolve(xhr.response);
            } else {
                reject(xhr.statusText || "请求失败");
            }
        };
        xhr.onerror = () => reject(xhr.statusText || "网络错误");
        xhr.send(obj.body);
    });
}

2. 为Promise添加错误捕获

不管用await还是链式调用,都必须捕获reject,避免未处理Promise拒绝:

  • 用await+try/catch的写法:
try {
    const data = await request({url: "test.html"});
    document.getElementById("targetDiv").innerHTML = data.toString();
} catch (err) {
    console.error("加载本地文件失败:", err);
}
  • 用then+catch的链式写法:
request({url: "test.html"})
    .then(data => { 
        document.getElementById("targetDiv").innerHTML = data.toString();
    })
    .catch(err => {
        console.error("加载本地文件失败:", err);
    });

补充说明

Safari对本地文件的权限管控比Chrome更严格,file://协议下的请求状态返回差异是常见兼容性问题。因为你仅用于本地测试,上述修改完全满足需求,无需考虑额外安全限制。

内容的提问来源于stack exchange,提问作者jorge_quintanilha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 05:22:56