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

Nginx反向代理Jelastic服务器时仅PUT/POST请求出现CORS错误

解决Jelastic环境下Nginx 1.24.0 HTTP3/QUIC的CORS问题

问题现象

  • 原有Jelastic服务器运行正常,添加Nginx流量分发器后,GET请求与登录POST请求可正常工作,但登录后的POST、PUT请求出现CORS错误(预检OPTIONS请求正常,仅实际请求报错)
  • Firefox、Linux设备均出现相同错误,Safari可正常运行
  • 关闭Chrome的QUIC协议后,错误消失;直接使用Nginx负载均衡器无此问题,仅在Jelastic流量分发器下出现

错误详情

CORS报错信息

Access to XMLHttpRequest at '' from origin 'xyz' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

错误响应头(状态码500)

Content-Length: 383
Content-Type: text/html
Date: Thu, 20 Jul 2023 11:46:56 GMT
Etag: "6194d09a-17f"
Server: nginx

Safari正常响应头特征

包含Access-Control-Allow-Origin: *等完整CORS头

不同浏览器请求对比

Brave/Chrome(使用HTTP3/QUIC)请求

curl 'https://dev-backend.xyz.app/api/collections/722/collectibles/4708' \
  -X 'PUT' \
  -H 'authority: dev-backend.xyz.app' \
  -H 'accept: application/json, text/plain, */*' \
  -H 'accept-language: en-GB,en;q=0.9' \
  -H 'authorization: Bearer abcdef' \
  -H 'content-type: application/json' \
  -H 'origin: https://dev.xyz.app' \
  -H 'referer: https://dev.xyz.app/' \
  -H 'sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Brave";v="114"' \
  -H 'sec-ch-ua-mobile: ?0' \
  -H 'sec-ch-ua-platform: "macOS"' \
  -H 'sec-fetch-dest: empty' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-site: same-site' \
  -H 'sec-gpc: 1' \
  -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' \
  --data-raw '{jsondata}'

Safari(使用HTTP2)请求

curl 'https://dev-backend.xyz.app/api/collections/722/collectibles/4708' \
-X 'PUT' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/plain, */*' \
-H 'Authorization: Bearer abcdef' \
-H 'Sec-Fetch-Site: same-site' \
-H 'Accept-Language: en-GB,en;q=0.9' \
-H 'Accept-Encoding: gzip, deflate, br' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Host: dev-backend.xyz.app' \
-H 'Origin: https://dev.xyz.app' \
-H 'Content-Length: 944' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5.1 Safari/605.1.15' \
-H 'Referer: https://dev.xyz.app/' \
-H 'Connection: keep-alive' \
-H 'Sec-Fetch-Dest: empty' \
--data-binary '{jsondata}'

当前Nginx配置

location / {
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' $http_origin;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept';
        add_header 'Access-Control-Max-Age' 86400;
        return 204;
    }

    add_header 'Access-Control-Allow-Origin' $http_origin;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Headers' 'Range, Authorization, Content-Type, x-session-token';
    add_header 'Access-Control-Max-Age' 3600;

    proxy_pass http://common;
}

解决建议

  1. 强制所有响应添加CORS头
    Nginx默认仅在2xx/3xx响应中执行add_header,而当前错误响应为500状态码,导致CORS头未被添加。需添加always参数确保无论响应状态如何都注入头信息:
    location / {
        if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' $http_origin always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;
            add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, Range, x-session-token' always;
            add_header 'Access-Control-Max-Age' 86400 always;
            return 204;
        }
    
        add_header 'Access-Control-Allow-Origin' $http_origin always;
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
        add_header 'Access-Control-Allow-Credentials' 'true' always;
        add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, Range, x-session-token' always;
        add_header 'Access-Control-Max-Age' 3600 always;
    
        proxy_pass http://common;
    }
    
  2. 验证Jelastic流量分发器的HTTP3头传递
    由于直接使用Nginx负载均衡器无问题,需确认Jelastic流量分发器是否完整转发HTTP3请求的Origin头。可在Nginx中添加日志记录$http_origin,验证HTTP3请求的Origin值是否正确:
    log_format cors_log '$remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_origin"';
    access_log /var/log/nginx/cors_access.log cors_log;
    
  3. 统一CORS配置规则
    目前OPTIONS请求与普通请求的Access-Control-Allow-Headers配置不一致,建议统一设置,避免因头信息不匹配引发的问题。

内容的提问来源于stack exchange,提问作者halster

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 16:17:08