angular - Angular,错误拦截器,在不同的 url 上重试原始请求
问题描述
几个月前我开始在一个新项目上使用 Angular,但现在我需要编写一个更复杂的错误拦截器,它可以检测后端 API 何时关闭。
拦截器需要检测 HTTP 错误代码,如果服务器关闭,我需要向第三方 API 服务器执行请求并获取可用后端服务器 URL 的列表,从该列表中 ping 每个服务器,直到找到一个 UP并重试原始请求(基本上是更改基本 URL)。
以下是拦截器需要执行的步骤:
- 检查错误代码,如果代码为0,则调用方法处理问题
- 向不同的 API 执行请求并获取所有可用服务器的列表
- 遍历列表并从该列表中 ping 每个服务器。
- 找到可用服务器后,重试原始请求。
就我而言,通常的要求是获取项目列表:
getProjects() {
return this.http.get<IProject[]>('/projects');
}
缺少基本 URL,因为我使用另一个拦截器动态添加它。
获取可用后端服务器 URL 列表的方法:
getRoutes() {
return this.http.get<IRoute[]>(this.API_URL + '/routes');
}
以及可以 ping 服务的服务
ping(url: string) {
return this.http.get(url, { observe: 'response', responseType: 'text' });
}
直到这里一切都按预期工作。
现在拦截器:
intercept(request, next) {
return next.handle(request).pipe(
catchError((error: any) => {
if (error.status === 0) {
return this.handleServerDownError(request, next);
}
return throwError(error);
})
);
}
handleServerDownError(request, next) {
return this.routesService.getRoutes().pipe(
map(routes => {
routes.map((route: IRoute) =>
this.pingService.ping(route.value).subscribe(res => {
if (res.status === 200) {
const updatedReq = request.clone({
url: route.value + request.url
});
return next.handle(updatedReq);
}
})
);
})
);
}
我几乎开始工作了,但是如果被 ping 的服务器关闭并且我收到相同的错误代码并且我进入无限循环,那么当然 ping 方法会返回相同的错误代码。
有什么想法让它工作吗?也许我可以改变 ping 方法返回不同的代码?
另外,在找到第一个可用服务器后,如何停止在 map 函数中进行迭代?
提前致谢!
解决方案
我几乎开始工作了,但是如果被 ping 的服务器关闭并且我收到相同的错误代码并且我进入无限循环,那么当然 ping 方法会返回相同的错误代码。
为此,您可以在 ping url 的末尾添加一个虚拟路径(例如:http://something:8080/dummy_ping),以便您可以识别它是否是 if 条件内的 ping 请求
if (error.status === 0 && !this.isDummyRequest(request)) {
return this.handleServerDownError(request, next);
}
...
...
private isDummyRequest(request: HttpRequest<any>): boolean {
if (request.url.includes('/dummy_ping')) {
return true;
} else {
return false;
}
}
另外,在找到第一个可用服务器后,如何停止在 map 函数中进行迭代?
可以选择使用 find 函数而不是 map
推荐阅读
- scala - 在 Scala 中获取一系列大小的子集?
- oracle - 无法连接到在 docker 容器中运行的 oracledb
- amazon-web-services - Terraform:在应用之前无法确定数据源上的长度()?
- wordpress - 使用 .htaccess (Wordpress) 重定向具有多个 ID 的动态 URL
- mysql - “新的临时证书过期太快:当前时间:”M
- css - 删除列之间的间距/填充
- python - How does the for keyword affect *in* expressions?
- reactjs - 如何正确初始化 React 中的函数?
- php - Laravel 5.8 - 如何将文件从存储目录移动到公共目录?
- php - 不能在 HTML_dom 和 curl 中刮价格