跨源请求被阻止

时间:2021-03-30 14:34:29

标签: reactjs api nginx axios cors

我正在尝试使用 ReactJS 从 orthanc 服务器加载图像。由于 orthanc 不支持 CORS,我已经使用 nginx 设置了代理服务器。 Nginx 和 orthanc 在 docker 容器中,nginx 可以通过 http://orthanc:8042 与 orthanc 对话。 按照我的 nginx 配置文件:

events {
    worker_connections 1024;
}
http {
   server {
      listen 80 default;
      server_name 127.0.0.1 localhost;
   
      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_header Access-Control-Allow-Credentials 'true';
         add_header Access-Control-Allow-Origin '*';
         add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
         add_header Access-Control-Allow-Headers 'Authorization, Origin, X-Requested-With, Content-Type, Accept'; 
          
      }
   }
}

如果我用邮递员尝试请求,来自 nginx 的 CORS 标头似乎可以工作:

Postman response header

但是如果我尝试通过 ReactJS / axios 调用 api,我就会被 CORS 策略阻止:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8085/orthanc/instances/5cd65944-8a37c5f3-ecd23660-3238d171-41728b44/preview. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).


Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8085/orthanc/instances/5cd65944-8a37c5f3-ecd23660-3238d171-41728b44/preview. (Reason: CORS request did not succeed).

这是我的要求:

import axios from 'axios'
export const PacsService = {
    find,
    authToken,
}
function  find() {
    authToken()
    var response = instance.get('http://localhost:8085/orthanc/instances/5cd65944-8a37c5f3-ecd23660-3238d171-41728b44/preview')
    console.log(response.data)

     
}

// -- Axios https://github.com/axios/axios#config-defaults
const instance =  axios.create({
    //baseURL: `${config.ORTHANC_BASE_URL}`,
    headers: {
        'Content-Type': 'application/json'
    }
})

instance.interceptors.request.use(request => {
    console.log('Starting Request', JSON.stringify(request, null, 2))
    return request
})

instance.interceptors.response.use(response => {
    console.log('Response:', JSON.stringify(response, null, 2))
    console.log(response)
    return response
    
})

// -- Helper functions
export function authToken() {
    // set default header to be sent with every request
    instance.defaults.headers.common.Authorization = `Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXX`
}

1 个答案:

答案 0 :(得分:1)

与 Postman 通话时,您只发送 GET 请求。 浏览器总是首先发送 OPTIONS 请求以检查 CORS 规则。

您只需使用 nginx 规则将每个请求转发到 orthanc 服务器。但是 orthanc 不支持 OPTIONS 请求,并且会向您发送错误响应 - 例如 error 404。发生这种情况时,浏览器会因 CORS 错误而阻止您的请求。通过向您的 orthanc URL 发送 OPTIONS 请求而不是 GET 请求,您应该能够使用 Postman 重新创建此错误。

作为一种解决方法,您可以将 nginx 配置为每次向您的 orthanc 服务器发送 200 OK 请求时返回代码 OPTIONS。响应还必须包含 Access-Control-Allow 标头以让浏览器知道允许 CORS。在您的情况下,这看起来像这样:

      location  /orthanc/  {
         # always return code 200 with needed CORS headers
         if ($request_method = OPTIONS ) {
            add_header Content-Type text/plain;
            add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type' always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
            add_header 'Access-Control-Allow-Origin' '*' always;
            return 200;
         }

         proxy_pass http://orthanc:8042;
         rewrite /orthanc(.*) $1 break;
         add_header 'Access-Control-Allow-Origin' '*';
      }

需要标头末尾的 always 标签,否则它不会返回此标头,因为 orthanc 不会回复 200 OK 响应