Angular应用手动触发REST API请求时出现请求失败问题
Angular HttpClient手动触发请求报错:TypeError: Failed to fetch
我有一个极简Angular应用,仅包含基础app组件。编写了使用Angular HttpClient发起GET请求到REST API的函数(API返回测试模拟数据):
- 在
ngOnInit生命周期钩子中调用该函数时一切正常 - 点击页面按钮手动触发同一函数时,出现如下错误:
Status : 0 Error : TypeError: Failed to fetch at http://localhost:55651/polyfills.js:1255:30 at proto.<computed> (http://localhost:55651/polyfills.js:782:16) at _FetchBackend.<anonymous> (http://localhost:55651/@fs/C:/Users/morgan/issue/.angular/cache/17.3.2/vite/deps/chunk-EONTFRYP.js?v=baac2411:1128:35) at Generator.next (<anonymous>) at http://localhost:55651/@fs/C:/Users/morgan/issue/.angular/cache/17.3.2/vite/deps/chunk-KJBDP7EP.js?v=baac2411:49:61 at new ZoneAwarePromise (http://localhost:55651/polyfills.js:1185:21) at __async (http://localhost:55651/@fs/C:/Users/morgan/issue/.angular/cache/17.3.2/vite/deps/chunk-KJBDP7EP.js?v=baac2411:33:10) at _FetchBackend.doRequest (http://localhost:55651/@fs/C:/Users/morgan/issue/.angular/cache/17.3.2/vite/deps/chunk-EONTFRYP.js?v=baac2411:1124:12) at Observable2._subscribe (http://localhost:55651/@fs/C:/Users/morgan/issue/.angular/cache/17.3.2/vite/deps/chunk-EONTFRYP.js?v=baac2411:1117:12) at Observable2._trySubscribe (http://localhost:55651/@fs/C:/Users/morgan/issue/.angular/cache/17.3.2/vite/deps/chunk-KJBDP7EP.js?v=baac2411:1131:19)
通过shell发起同一GET请求无异常,Nginx的access.log显示两次请求均返回200:
MY-IP - - [07/Apr/2024:14:12:58 +0000] "GET /tmpTest HTTP/1.1" 200 26 "-" "node" My-IP - - [07/Apr/2024:14:13:00 +0000] "GET /tmpTest HTTP/1.1" 200 26 "http://localhost:55651/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 OPR/108.0.0.0"
首次请求由node发起,第二次由浏览器发起。本地部署的Flask REST API无此问题,但部署在Nginx+Gunicorn的服务器上时出现错误。
解决方案
1. 修复CORS配置
浏览器发起的请求会携带Origin头,而服务器端(node)发起的请求不会。Nginx+Gunicorn环境下可能未正确配置跨域响应头,导致浏览器拦截响应。
在Flask中配置CORS:
使用flask-cors扩展:from flask import Flask from flask_cors import CORS app = Flask(__name__) CORS(app, origins="http://localhost:55651") # 指定允许的前端地址 @app.route('/tmpTest') def tmp_test(): return "test data"在Nginx中配置CORS:
若通过Nginx反向代理,直接在Nginx配置中添加响应头:server { # ... 其他配置 location /tmpTest { add_header Access-Control-Allow-Origin "http://localhost:55651"; add_header Access-Control-Allow-Methods "GET, OPTIONS"; add_header Access-Control-Allow-Headers "Content-Type"; if ($request_method = OPTIONS) { return 204; # 处理预检请求 } proxy_pass http://your-gunicorn-upstream; # 替换为你的Gunicorn地址 } }
2. 检查Zone.js上下文
Angular依赖Zone.js管理异步操作,按钮点击的回调可能意外跑出Zone上下文,导致HttpClient请求异常。尝试用NgZone包裹请求逻辑:
import { Component, OnInit, NgZone } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-root', template: '<button (click)="onFetchData()">手动请求</button>' }) export class AppComponent implements OnInit { constructor(private http: HttpClient, private zone: NgZone) {} ngOnInit() { this.fetchData(); } onFetchData() { this.zone.run(() => { this.fetchData().subscribe({ next: data => console.log(data), error: err => console.error(err) }); }); } private fetchData() { return this.http.get('http://your-api-url/tmpTest'); } }
3. 排查Nginx/Gunicorn连接问题
- 查看Nginx的
error.log,检查是否有连接超时、响应截断等错误 - 调整Gunicorn的worker配置,比如使用异步worker(gevent)提升并发处理能力:
gunicorn --workers=4 --worker-class=gevent your_app:app - 在Nginx配置中禁用缓存,避免响应被异常缓存:
location /tmpTest { proxy_no_cache 1; proxy_cache_bypass 1; proxy_pass http://your-gunicorn-upstream; }
内容的提问来源于stack exchange,提问作者Morgan
相关产品推荐
相关产品推荐

