You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

浏览器请求的自定义Header无法到达Flask后端,但Curl请求正常

浏览器请求的自定义Header无法到达Flask后端,但Curl请求正常

我来帮你一步步排查并解决这个问题,先从最明显的问题入手,再深入分析CORS和Header传递的细节:

1. 先修复前端AJAX的语法错误

看你的AJAX代码里,Authorization字段有个多余的右括号:

'Authorization': `Bearer ${access_token)}`
// 这里多了一个),应该改成:
'Authorization': `Bearer ${access_token}`

这个语法错误可能会导致整个请求发送失败,自定义Header根本没被浏览器发送出去。先修复这个问题,再测试。

2. 确认浏览器实际发送了Header

打开浏览器开发者工具的Network标签,找到你的POST请求:

  • 查看Request Headers部分,确认X-custom-1X-custom-2Authorization是否存在
  • 如果这些Header没出现在Request Headers里,说明前端请求的构造有问题,先确保AJAX代码没有其他语法错误

3. 验证CORS预检请求(OPTIONS)的响应

浏览器发送带自定义Header的POST请求前,会先发送一个OPTIONS预检请求,确认服务器允许这些Header:

  • 在Network标签找到OPTIONS请求,查看Response Headers里的Access-Control-Allow-Headers,确认它包含X-custom-1X-custom-2AuthorizationContent-Type
  • 如果没有,说明你的Flask-CORS配置可能没生效,检查:
    • resources={r"*": ...}是否覆盖了你的/api/some_endpoint路径(r"*"是匹配所有路径,应该没问题,但如果你的路由有特殊前缀可以再确认)
    • allow_headers里的自定义Header名称是否和前端完全一致(比如有没有拼写错误,比如X-custom-1写成X-custom1

4. Flask后端正确获取自定义Header的方式

在Flask中,自定义Header的获取有两种方式:

方式1:通过request.headers获取

Flask的request.headers是一个大小写不敏感的对象,你可以直接用原始的Header名称(不区分大小写)获取:

@app.before_request
def before_request():
    custom1 = request.headers.get('X-custom-1')
    custom2 = request.headers.get('X-custom-2')
    auth_header = request.headers.get('Authorization')
    print(f"X-custom-1: {custom1}, X-custom-2: {custom2}")

方式2:通过request.environ获取

WSGI规范会把自定义Header转换为HTTP_前缀的大写形式(比如X-custom-1变成HTTP_X_CUSTOM_1),你也可以通过environ直接获取:

@app.before_request
def before_request():
    custom1 = request.environ.get('HTTP_X_CUSTOM_1')
    custom2 = request.environ.get('HTTP_X_CUSTOM_2')
    print(f"X-custom-1 from environ: {custom1}")

5. 额外排查点

  • 如果你在before_request里拦截了OPTIONS请求,会导致Flask-CORS无法自动处理预检,确保你的代码没有手动处理OPTIONS请求
  • 检查是否有其他Flask中间件(比如认证中间件、日志中间件)干扰了Header的传递,可以暂时禁用其他中间件测试
  • 本地开发时,浏览器可能会缓存CORS预检响应,强制刷新页面(Ctrl+Shift+R)或者清空浏览器缓存后再测试

完整修复后的代码示例

前端AJAX:

$.ajax({
  url: 'http://localhost:5000/api/some_endpoint',
  method: 'POST',
  headers: {
    'X-custom-1': '123',
    'X-custom-2': 'abc',
    'Authorization': `Bearer ${access_token}` // 修复了多余的括号
  },
  data: JSON.stringify({
    key1: 'value1',
    key2: 'value2'
  }),
  contentType: 'application/json'
});

Flask后端获取Header:

from flask import Flask, request
from flask_cors import CORS

app = Flask(__name__)
CORS(app, 
     resources={r"*": {"origins": "http://localhost:4200"}},
     allow_headers=["Authorization", "Content-Type", "X-custom-1", "X-custom-2"],
     methods=["GET", "POST", "OPTIONS"])

@app.before_request
def before_request():
    # 用headers获取
    custom1 = request.headers.get('X-custom-1')
    custom2 = request.headers.get('X-custom-2')
    print(f"Received custom headers: X-custom-1={custom1}, X-custom-2={custom2}")
    
    # 或者用environ获取
    custom1_env = request.environ.get('HTTP_X_CUSTOM_1')
    print(f"X-custom-1 from environ: {custom1_env}")

@app.route('/api/some_endpoint', methods=['POST'])
def some_endpoint():
    return {"status": "success"}

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

备注:内容来源于stack exchange,提问作者pimi

火山引擎 最新活动