You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 15:33:15