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

ReactJS通过Nginx代理访问Orthanc服务器图片时遭遇CORS跨域拦截问题

Why Postman Works But React/Axios Gets CORS Blocked

Let's break down the two key issues here and fix them step by step:

1. Browsers Send OPTIONS Preflight Requests (Postman Doesn't)

When you make a cross-domain request with custom headers (like your Authorization header), browsers first send an OPTIONS preflight request to verify if the server allows the actual request. Postman skips this preflight check by default, which is why it works seamlessly.

Your original Nginx config didn't handle this OPTIONS request properly—it was forwarding the request to Orthanc (which has no CORS support at all), so the preflight response lacked the required CORS headers, triggering the browser's block.

2. Credentials + Wildcard Origin Conflict

You set Access-Control-Allow-Credentials: true but paired it with Access-Control-Allow-Origin: *. Browsers reject this combination outright: if you allow credentials (like auth headers or cookies), you can't use a wildcard origin—you have to specify exact, trusted domains.


Fix #1: Update Nginx Config to Handle Preflight & Fix Origin Conflict

Here's the corrected Nginx config with key improvements:

events { worker_connections 1024; }

# Optional: Use a map to safely allow multiple local dev origins (e.g., localhost:3000, localhost:8080)
map $http_origin $cors_origin {
    ~^http://localhost(:\d+)?$ $http_origin;
    # Add production domains here if needed:
    # ~^https://your-app-domain.com$ $http_origin;
    default "";
}

http {
    server {
        listen 80 default;
        server_name 127.0.0.1 localhost;
        
        # Handle OPTIONS preflight requests directly (don't forward to Orthanc)
        if ($request_method = OPTIONS) {
            add_header Access-Control-Allow-Credentials 'true' always;
            add_header Access-Control-Allow-Origin $cors_origin always;
            add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always;
            add_header Access-Control-Allow-Headers 'Authorization, Origin, X-Requested-With, Content-Type, Accept' always;
            return 204; # No content needed for preflight responses
        }

        location /orthanc/ {
            proxy_pass http://orthanc:8042;
            proxy_set_header HOST $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            rewrite /orthanc(.*) $1 break;
            
            # Add CORS headers to all responses (use `always` to include error responses)
            add_header Access-Control-Allow-Credentials 'true' always;
            add_header Access-Control-Allow-Origin $cors_origin always;
            add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always;
            add_header Access-Control-Allow-Headers 'Authorization, Origin, X-Requested-With, Content-Type, Accept' always;
        }
    }
}

Fix #2: Update Axios to Use Credentials

Since you enabled Allow-Credentials in Nginx, you need to tell Axios to send credentials (auth headers, cookies) with requests:

const instance = axios.create({
    //baseURL: `${config.ORTHANC_BASE_URL}`,
    headers: {
        'Content-Type': 'application/json'
    },
    // Enable credentials to match Nginx's Allow-Credentials setting
    withCredentials: true
})

Why This Works

  • Preflight Handling: The OPTIONS request is intercepted and returns valid CORS headers immediately, so the browser approves the actual GET request.
  • Valid Origin Setup: The map directive ensures we only allow trusted origins (like your local React dev server) instead of a wildcard, fixing the credentials conflict.
  • Always Include Headers: The always flag ensures CORS headers are added even if the response is an error (e.g., 401 Unauthorized), preventing unexpected blocks.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 12:07:38