如何让Angular代理将取消请求传递至ASP.NET Core服务?
Angular代理下请求取消信号无法传递到ASP.NET Core的问题解决
复现步骤:
- 在Visual Studio 2022中创建全新的Angular + ASP.NET Core项目
- 在
WeatherForecastController中添加以下接口方法:[HttpGet, Route("test")] public async Task Test(CancellationToken cancellationToken) { try { await Task.Delay(100_000, cancellationToken); } catch (OperationCanceledException e) { Console.WriteLine(e); } }
- 项目启动后,API托管于
https://localhost:7073/,Angular应用托管于https://localhost:4200/,通过proxy.conf.js配置代理映射请求- 直接访问
https://localhost:7073/weatherforecast/test,取消页面加载会触发后端的CancellationToken;但访问https://localhost:4200/weatherforecast/test时,取消页面加载无法终止后端方法,方法会运行至结束
问题原因
Angular开发环境使用的webpack-dev-server代理默认不会将客户端的请求取消信号(如浏览器中断页面加载触发的连接关闭事件)转发到后端。代理会保持与后端的连接直到请求自然完成,导致后端的CancellationToken无法感知到客户端的取消操作。
是否为已知Bug?
这不属于Bug,是代理的默认设计行为。代理的默认逻辑是避免意外中断后端请求,因此不会主动在客户端断开时终止与后端的连接。
可行解决办法
可以通过修改proxy.conf.js的配置,监听客户端连接关闭事件,主动终止代理到后端的请求,从而将取消信号传递给ASP.NET Core后端:
const proxyConfig = [ { context: ['/weatherforecast'], target: 'https://localhost:7073', secure: false, // 开发环境下忽略HTTPS证书验证 onProxyReq: (proxyReq, req, res) => { // 监听客户端连接关闭事件,终止代理请求 req.on('close', () => { proxyReq.abort(); }); } } ]; module.exports = proxyConfig;
配置说明
onProxyReq钩子:在代理请求发送到后端前触发,这里监听客户端请求的close事件(浏览器取消页面加载时,客户端连接会关闭)proxyReq.abort():主动终止代理到后端的请求,此时后端的CancellationToken会触发OperationCanceledException,达到终止方法执行的效果
如果是在Angular应用内部发起HTTP请求(而非直接地址栏访问),还可以结合Angular的HttpClient与AbortController主动取消请求,这种情况下代理也会将取消信号传递到后端:
import { HttpClient } from '@angular/common/http'; import { AbortController } from '@angular/common/http'; // 在组件或服务中 const abortController = new AbortController(); this.http.get('/weatherforecast/test', { signal: abortController.signal }) .subscribe(); // 需要取消请求时调用 abortController.abort();
内容的提问来源于stack exchange,提问作者wpfwannabe
相关产品推荐
相关产品推荐

