我在生产环境中的 10% 请求中出现以下错误。
"error": "[ProgressEvent]",
"headers": "[ti]",
"message": "Http failure response for https://api.xxxxxx:5000/api/public-web/files: 0 Unknown Error",
"name": "HttpErrorResponse",
"ok": false,
"status": 0,
"statusText": "Unknown Error",
"url": "https://api.xxxxxx:5000/api/public-web/files"
日志来自Sentry。
堆栈:
首先,我认为问题与 CORS 有关,但尽管我已经在后端配置了 CORS,但我还在
web-config (IIS)
中的服务器上的所有响应标头中添加了以下内容:
access-control-allow-headers: *
access-control-allow-methods: GET,POST,PATCH,PUT,DELETE,OPTIONS
access-control-allow-origin: *
我仅在 IIS 上使用 web.config 中的上述自定义标头介绍了 CORS,而不是在应用程序端。
我还读到,它可能与糟糕的互联网连接有关(根据 Angular 官方文档),但这不是这里的问题(也许,但只是 10% 的情况下的 1%)。
用户尝试将网络连接从WIFI更改为移动,但仍然出现相同的问题。
我也遇到过同样的情况。 Angular + CORS 正确配置 + 许多带有“HTTP 0 Unknown Error”的 Sentry 问题。
您走在正确的道路上。当某些用户的互联网/Wi-Fi 连接不稳定/不良导致某些请求失败时,就会发生这种情况。
我通过实现重试拦截器来重试那些失败的请求,成功地减少了这些错误,从而改善了用户体验:
import { HttpErrorResponse, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { retry, timer } from 'rxjs';
// These variables have to stay outside the class because of 'this' keyword binding issues
const maxRetries = 2;
const delayMs = 2000;
@Injectable()
export class RetryInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<unknown>, next: HttpHandler) {
// Pass the request to the next request handler and retry HTTP 0 errors 2 times with a 2-second delay
return next.handle(request).pipe(retry({ count: maxRetries, delay: this.delayNotifier }));
}
delayNotifier(error: any, retryCount: number) {
if (error instanceof HttpErrorResponse && error.status === 0) {
return timer(delayMs);
}
// re-throw other errors for anything else that might be catching them
throw error;
}
}
即使使用此重试拦截器,您仍然会遇到一些错误,因为我们无法控制用户的互联网连接:)