nginx / chrome을 사용한 CORS (Cross Origin Resource Sharing)


13

다음과 같은 세그먼테이션이있는 웹 사이트가 있습니다.

api.example.com 
developers.example.com 
example.com

둘 다 허용 하고 AJAX 요청을 example.com하고 싶습니다 .developers.example.comapi.example.com

api.example.com유니콘이 제공하는 Rack 앱 인 지금까지의 nginx 구성 은 다음과 같습니다.

upstream app_server {
  server unix:/tmp/api.example.com.sock fail_timeout=0;
}

server {
       listen 80;
       server_name api.example.com;
       access_log /home/nginx/api.example.com/log/access.log;
       error_log /home/nginx/api.example.com/log/error.log;
       location / {
         add_header 'Access-Control-Allow-Origin' 'http://example.com,http://developers.example.com';
         add_header 'Access-Control-Allow-Credentials' 'true';
         add_header 'Access-Control-Allow-Headers' 'Content-Type,Accept';
         add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';

         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host $http_host;
         proxy_redirect off;
         proxy_pass http://app_server;
       }

}

내 독서를 바탕으로, 이것은 내가하려는 일에 충분해야합니다.

옵션은 응답 :

HTTP/1.1 200 OK
Server: nginx/0.7.67
Date: Sat, 28 Apr 2012 17:20:08 GMT
Content-Type: application/json
Connection: close
Status: 200 OK
Content-Length: 0
Access-Control-Allow-Origin: http://developers.example.com,http://example.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type,Accept
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE

그러나 Chrome 콘솔에서 다음을 시도하면

$.ajax("http://api.example.com", {
  type: 'get',
  contentType: "application/json",
  accept: "application/json"
}).success(function(data){
  console.log("success!", data);
}).fail(function(jqxhr, statusText){
  console.log("fail!", jqxhr, statusText);
})

내가 참조:

XMLHttpRequest cannot load http://api.example.com/. Origin
http://developers.example.com is not allowed by Access-Control-Allow-Origin.

http://example.com도 마찬가지입니다 .

내가 무엇을 놓치고 있습니까?

내가 설정 한 경우 Access-Control-Allow-Origin*그때 참조 :

HTTP/1.1 200 OK
Server: nginx/0.7.67
Date: Sat, 28 Apr 2012 17:28:41 GMT
Content-Type: application/json
Connection: close
Status: 200 OK
Content-Length: 0
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type,Accept
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE

그러나 jQuery 요청은 여전히 ​​실패하지만 크롬은 사전 비행이 OPTIONS실패했음을 강조합니다 (반환되었지만 200 OK).

답변:


17

CORS 사양 에 따르면 여러 원점이 사용하는 쉼표가 아닌 공백으로 구분되어야 하므로이 헤더를 보내보십시오.

Access-Control-Allow-Origin: http://developers.example.com http://example.com

모질라 문서는 그 여전히 보내는 작업 시도를하지 않도록 경우, 비록 다수의 기원을 언급하지 않습니다

Access-Control-Allow-Origin: http://developers.example.com

작동하면 허용되는 목록과 일치하는 경우 클라이언트가 보낸 헤더 Access-Control-Allow-Origin값을 포함 하는 헤더 를 반환하도록 nginx 또는 애플리케이션 서버를 구성해야 Origin합니다. 다음과 같은 (예상치 않은) nginx 구성과 같은 것이 그렇게 할 수 있습니다.

if ($http_origin ~ "^(http://developers.example.com|http://example.com)$") {
    add_header "Access-Control-Allow-Origin" $http_origin;
}

이것은 내가 결국 한 일의 일부입니다. 또한 Access-Control-Allow-Header헤더를 제거하고 jQuery 호출을 다음과 같이 수정 $.ajax("http://api.example.com", { type: 'get', crossDomain: true}) 했습니다. OPTIONS프리 플라이트가 전혀 발생 하지 않았습니다 .
John Ledbetter

1
참고 : 주어진 해결책이 효과가 없다면 이것이것을 읽으십시오 . 깨달았으며 작동하지 않는 이유를 찾을 수 있습니다.
its_me

4

를 사용하여 ifA의 location이 같은 nginx를 구성 블록 :

if ($http_origin ~ "^(http://developers.example.com|http://example.com)$") {
    add_header "Access-Control-Allow-Origin" $http_origin;
}

nginx가 이상한 일을하게하십시오. 특히, proxy_pass그리고 try_files예상대로 작동하지 않습니다. 자세한 내용은 http://wiki.nginx.org/IfIsEvil 을 참조 하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.