使用Cloudflare时捕获JavaScript fetch失败的问题:缺少CORS标头429。

3
我正在使用 Fetch 来在JavaScript中进行跨域请求。
Cloudflare(代理我的流量)有时会返回429(速率限制)。
当它们返回429时,它们不包括Access-Control-Allow-Origin头。
因此,现在我的具有模式'cors'的fetch失败,并抛出TypeError。
如何捕获这种情况,而不是像网络错误等其他原因抛出异常?

screenshot

我的代码如下:
    try {
        let response = await fetch(uri, config); // this throws
        if (!response.ok) { // this line does not run
            throw response.statusText;
        }
        let json = await response.json();
        return json;
    } catch (e) {
        console.log(e.message); // "Failed to fetch"
    }

查看MDN文档,我不确定是否可以将此429错误与其他网络错误分开检测?

当遇到网络错误或服务器端CORS配置错误时,fetch() Promise会因TypeError而拒绝,尽管这通常意味着权限问题或类似问题

response


2
你是否正在使用“fetch-interceptor”或类似的库,并在代码其他地方(全局)处理这些请求? - Matt U
@MattU,这可能与它通过cloudflare进行CORS有关?我已经添加了响应的屏幕截图。 - d-_-b
1
你所请求的服务器必须重新配置以在4xx错误中添加Access-Control-Allow-Origin头。问题中显示的响应标头不包括该标头;因此,如果这是跨源请求,则浏览器会阻止您的前端代码访问响应,包括状态。检查开发工具控制台,您会看到浏览器记录了CORS错误。大多数服务器默认情况下不会在4xx错误中添加Access-Control-Allow-Origin头 - 而只会在2xx成功响应中添加。缺少这个,浏览器将不允许您访问状态。 - sideshowbarker
谢谢@sideshowbarker,我刚刚意识到这一点,并更新了问题并提供了更多上下文,如果您有任何其他想法,请告诉我! - d-_-b
2
你唯一能够从前端JavaScript代码解决这个问题的方法就是添加某种限流措施,以避免触发引起429错误的速率限制。否则,在仅有前端代码的情况下无法解决此问题。因此,你需要使用CORS代理(例如https://cors-anywhere.herokuapp.com/),或者从服务器端后端代码发出请求(因为那里没有同源限制),或者尝试让Cloudflare在429响应中添加Access-Control-Allow-Origin头信息。 - sideshowbarker
显示剩余4条评论
2个回答

0

简而言之,你无法这样做,这是有意为之的。

唯一可以解决这个问题的地方是服务器端。要么需要更改/配置Cloudflare以发送适当的标头,要么使用其他服务在错误时发送标头。

如果没有服务器端更改,错误将是通用的CORS错误。

另一个选择可能是构建类似于“iframe代理”的东西,从而让您完全规避CORS。


-1

当用户在给定时间内发送过多请求时,会返回状态码:429。这意味着事件监听器正在发出多个请求(我认为是这样)。

因此,要防止事件监听器发出多个请求,请使用:

event.stopImmediatePropagation();

如果同一事件类型的多个侦听器附加到同一元素,则按照它们添加的顺序调用它们。如果在这样的调用期间调用stopImmediatePropagation(),则不会调用任何剩余的侦听器。
在MDN文档这里中了解更多信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接