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

Google Cloud部署的Python Flask API跨域(CORS)问题求助

解决部署在Google Cloud上的Flask API跨域(CORS)问题

问题现象

跨域调用API时触发CORS拦截,报错信息:

Access to XMLHttpRequest at 'https://myapi.app/ask_question' from origin 'http://localhost:4200' (or 'https://mywebsite.dev') has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

前端调用代码(Angular)

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';

interface ChatMessage {
  text: string;
  isUserMessage: boolean;
}

@Component({
  selector: 'app-chatbot',
  templateUrl: './chatbot.component.html',
  styleUrls: ['./chatbot.component.css']
})
export class ChatbotComponent {
  isChatbotCollapsed = false;
  userInput: string = '';
  chatMessages: ChatMessage[] = [];

  constructor(private http: HttpClient) {}

  sendMessage() {
    const userMessage = this.userInput;

    this.chatMessages.push({ text: userMessage, isUserMessage: true });

    const apiUrl = 'https://myapi.app/ask_question';
    //const apiUrl = 'http://127.0.0.1:5000/ask_question';
    const payload = { input: userMessage };

    this.http.post(apiUrl, payload).subscribe(response => {
      const apiResponse = response as { output: string };
      const botResponse = apiResponse.output;

      this.chatMessages.push({ text: botResponse, isUserMessage: false });
    });

    this.userInput = '';
  }
}

后端Flask API代码(原代码)

import json
import os
from flask import Flask, request
from flask_cors import CORS


app = Flask(__name__)
CORS(app, resources={r"/*": {"origins":"https://mywebsite.dev"}})


@app.route('/ask_question', methods=['POST', 'OPTIONS'])
def ask_question():
    if request.method == 'OPTIONS':
        response = make_response()
        response.headers.add('Access-Control-Allow-Origin', 'https://mywebsite.dev')
        response.headers.add('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
        response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
        return response
    data = request.get_json()
    input_string = data['input']    
    output = 'hello, you said' + input_string
    
    response = make_response({'output': output})
    response.headers.add('Access-Control-Allow-Origin', 'https://mywebsite.dev')
    response.headers.add('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
    return response

if __name__ == '__main__':
    app.run()

已尝试但无效的方案

  • 明确配置域名:
    CORS(app, resources={r"*": {"origins": "*"}})
    
    或
    CORS(app, resources={r"/*": {"origins": ["https://mywebsite.dev/", "https://mywebsite.firebaseapp.com/"]}})
    
  • 添加响应头:
    @app.after_request
    def add_cors_headers(response):
        response.headers['Access-Control-Allow-Origin'] = 'https://mywebsite.dev'
        response.headers['Access-Control-Allow-Headers'] = 'Content-Type'
        response.headers['Access-Control-Allow-Methods'] = 'POST'
        return response
    
  • 在Google Cloud中配置CORS环境变量

问题根源与解决方案

关键错误点

  1. 缺少make_response导入:原代码中使用make_response但未从flask模块导入,导致运行时抛出异常,无法生成带有正确CORS头的响应。
  2. CORS配置重复冲突:同时使用flask-cors库和手动处理OPTIONS请求、添加响应头,容易导致头信息混乱,不符合浏览器的CORS校验规则。
  3. Google Cloud部署层可能覆盖响应头:如果API部署在Cloud Run、App Engine等平台,平台自身的配置可能会覆盖代码中设置的响应头。

修正后的Flask代码

import json
import os
from flask import Flask, request, make_response  # 补充导入make_response
from flask_cors import CORS


app = Flask(__name__)
# 允许生产域名和本地开发环境的跨域请求
CORS(app, resources={r"/*": {"origins": ["https://mywebsite.dev", "http://localhost:4200"]}})


@app.route('/ask_question', methods=['POST'])
def ask_question():
    data = request.get_json()
    input_string = data['input']    
    output = 'hello, you said ' + input_string
    
    # Flask会借助flask-cors自动添加正确的CORS响应头,无需手动处理
    return {'output': output}

if __name__ == '__main__':
    app.run()

部署环境补充配置

若使用Cloud Run:

在服务的编辑与部署新版本页面,进入「容器」→「高级设置」→「CORS」:

  • 允许的来源:https://mywebsite.dev,http://localhost:4200
  • 允许的方法:POST,OPTIONS
  • 允许的头:Content-Type

若使用App Engine:

在app.yaml中添加CORS配置:

handlers:
- url: /.*
  script: auto
  http_headers:
    Access-Control-Allow-Origin: "https://mywebsite.dev http://localhost:4200"
    Access-Control-Allow-Methods: "POST, OPTIONS"
    Access-Control-Allow-Headers: "Content-Type"

依赖确认

确保requirements.txt包含flask-cors:

flask
flask-cors

内容的提问来源于stack exchange,提问作者Jérémie Chassin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 23:34:57