2014-07-13 2 views
4

jQuery 문제인지 Compojure 문제인지 여부를 구분할 수 없습니다. 서버로 내장 부두를 사용하여, jQuery CORS 요청이 FireFox의 프리 플라이트 OPTIONS 요청에서 사망합니다.

function signup() { 

var signup_username = $('#signup_username').val(); 
var signup_password_1 = $('#signup_password_1').val(); 
var signup_password_2 = $('#signup_password_2').val(); 

$.ajax({ 
    type: "POST", 
    contentType: "application/json", 
    url: "http://localhost:40000/signup", 
data: 
    JSON.stringify({ 
     "signup_username": signup_username, 
     "signup_password_1": signup_password_1, 
     "signup_password_2": signup_password_2 
    }), 

    complete: function (data) { console.log(data); alert("Done. Look at the console.log to see the results."); }, 
    success: function (data) { console.log(data); }, 
    error: function (data) { console.log(data); }, 
    dataType: "json" 
}); 
} 

내가 서버에 작은 Clojure의 응용 프로그램을 쓰기 :

나는이 크로스 도메인 요청을하고 싶습니다. 내 로컬 컴퓨터에 테스트입니다

(defroutes app-routes 
    (GET "/" request (login-form request)) 
    (POST "/" request (login request)) 
    (OPTIONS "/" request (preflight request)) 
    (GET "/signup" request (signup-form request)) 
    (POST "/signup" request (signup request)) 
    (OPTIONS "/signup" request (preflight request)) 
    (route/resources "/") 
    (route/not-found "Page not found. Check the http verb that you used (GET, POST, PUT, DELETE) and make sure you put a collection name in the URL, and possibly also a document ID.")) 

,하지만 난 크로스 도메인을 테스트하려는, 그래서 나는이 개 다른 포트에서 동일한 응용 프로그램을 스핀 업 : :이처럼 내 Compojure의 경로를 정의 34001 및 40000 I 것 34001에서 파이어 폭스를 가리킨 다음 자바 스크립트가 40000

첫째로 크로스 도메인 호출을해야한다, 나는 컬이 테스트 :

* About to connect() to localhost port 40000 (#0) 
* Trying ::1... connected 
* Connected to localhost (::1) port 40000 (#0) 
> OPTIONS /signup HTTP/1.1 
> User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8x zlib/1.2.5 
> Host: localhost:40000 
> Accept: */* 
> 
< HTTP/1.1 200 OK 
< Date: Sun, 13 Jul 2014 20:43:43 GMT 
< Access-Control-Allow-Origin: localhost:40000 
< Access-Control-Allow-Methods: PUT, DELETE, POST, GET, OPTIONS, XMODIFY 
< Access-Control-Max-Age: 2520 
< Access-Control-Allow-Credentials: true 
< Access-Control-Request-Headers: x-requested-with, content-type, origin, accept 
< Access-Control-Allow-Headers: x-requested-with, content-type, origin, accept 
< Content-Type: application/json;charset=ISO-8859-1 
< Content-Length: 12 
< Server: Jetty(7.x.y-SNAPSHOT) 
< 
* Connection #0 to host localhost left intact 
* Closing connection #0 
를 :

curl -X OPTIONS --verbose http://localhost:40000/signup 

나에게 준다

그래서 내가 볼 것으로 예상되는 대부분의 헤더를 봅니다.

이제 Firebug를 사용하여 FireFox로 테스트합니다. Firebug는 프리 플라이트 OPTIONS 요청이 표시되지 않고 대신 단순히 오류가 표시됩니다.

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:40000/signup. This can be fixed by moving the resource to the same domain or enabling CORS. 

Strange. FireFox가 프리 플라이트 OPTIONS 요청을하고 있는지 궁금해합니다. 그래서 저는 Charles를 시작합니다. http://www.charlesproxy.com/

Charles는 저에게 FireBug가하지 않는 활동을 보여줍니다. 찰스는 나에게이 요청을 보여줍니다

OPTIONS /signup HTTP/1.1 
Host: localhost:40000 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:30.0) Gecko/20100101 Firefox/30.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-US,en;q=0.5 
Accept-Encoding: gzip, deflate 
Origin: http://localhost:34001 
Access-Control-Request-Method: POST 
Access-Control-Request-Headers: content-type 
Connection: keep-alive 
Pragma: no-cache 
Cache-Control: no-cache 

와 찰스 나에게이 응답을 보여줍니다 곳이 응답에서 왔는가되어 내가 직면 한 문제의

HTTP/1.1 200 OK 
Date: Sun, 13 Jul 2014 20:35:27 GMT 
Access-Control-Allow-Origin: http://localhost:34001 
Access-Control-Allow-Methods: DELETE, GET, POST, PUT 
Content-Type: application/octet-stream;charset=ISO-8859-1 
Content-Length: 18 
Server: Jetty(7.x.y-SNAPSHOT) 

preflight complete 

적어도 하나? 위 내 Compojure 노선에서 볼 수 있듯이,이 요청은 내가 다음과 같이 정의 된 "프리 플라이트"기능에 갔었어야 : 나는 컬이 테스트 때이 헤더를 볼 수 있습니다

(defn preflight [request] 
    "2014-07-13 - this is meant to enable CORS so our frontenders can do cross-browser requests. The browser should do a 'preflight' OPTIONS request to get permission to do other requests." 
    (print " IN PREFLIGHT ") 
    (println " headers host is: " (str (get-in request [:headers "host"]))) 
    (assoc 
     (ring.util.response/response "CORS enabled") 
    :headers {"Content-Type" "application/json" 
       "Access-Control-Allow-Origin" (str (get-in request [:headers "host"])) 
       "Access-Control-Allow-Methods" "PUT, DELETE, POST, GET, OPTIONS, XMODIFY" 
       "Access-Control-Max-Age" "2520" 
       "Access-Control-Allow-Credentials" "true" 
       "Access-Control-Request-Headers" "x-requested-with, content-type, origin, accept" 
       "Access-Control-Allow-Headers" "x-requested-with, content-type, origin, accept"})) 

가 아닌 경우 나는 FireFox를 사용한다. 또한 CURL을 사용할 때 터미널에 printlin 문이 인쇄되지만 FireFox는 인쇄되지 않습니다.

FireFox의 프리 플라이트 요청이 내 프리 플라이트 기능으로 이동하지 않습니다. 나는 그것이 실제로 어디로 가는지 알 수 없다. 도착한 응답이 내가 정의한 경로와 일치하지 않습니다.

누구나 무슨 일이 일어나고 있는지 아이디어가 있습니까?"

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 

가 어떻게 말합니까 :

http://chstrongjavablog.blogspot.com/2013/04/enabling-cors-for-jetty.html

UPDATE :이 의심스러운

나는이 사람이 최선을 시도하고 CORS는 사용할 수 없습니다 결정 통지 application/json "?

어떻게 FireFox가 만드는 프리 플라이트 요청을 제어 할 수 있습니까? 아니면 이것을하는 jQuery인가?

또한,이 반응은 매우 제한 보인다 :

Content-Type: application/octet-stream;charset=ISO-8859-1 

다시, 나는이 수익 원인을 알아낼 수 없습니다, 그래서 응답을 통해 많은 제어 할 수 없습니다.

내가 크롬이 테스트

, 나는이 오류 얻을 :

XMLHttpRequest cannot load http://localhost:40000/signup. Request header field Content-Type is not allowed by Access-Control-Allow-Headers. 

을 그리고, 다시, 나는이 사용 CURL을 테스트 할 때, 내가 올바른 헤더를 얻을, 아직 어떻게 든 크롬과 파이어 폭스는에 가고있다 내가 결코 정의하지 않은 길. 나는이 할 경우

는 :

curl -X OPTIONS --verbose http://localhost:40000/signup 

을 나는 이러한 응답 헤더를 얻을 :

< HTTP/1.1 200 OK 
< Date: Sun, 13 Jul 2014 22:45:00 GMT 
< Access-Control-Allow-Origin: localhost:40000 
< Access-Control-Allow-Methods: PUT, DELETE, POST, GET, OPTIONS, XMODIFY 
< Access-Control-Max-Age: 2520 
< Access-Control-Allow-Credentials: true 
< Access-Control-Allow-Headers: x-requested-with, content-type, origin, accept 
< Content-Type: application/json;charset=ISO-8859-1 
< Content-Length: 12 
< Server: Jetty(7.x.y-SNAPSHOT) 

"콘텐츠 유형"가 액세스 제어가-헤더 허용이 포함되어 있습니다. 그러나 Chrome과 FireFox 모두에서 브라우저는 내가 정의한 경로에서 오는 것 같지 않은 응답을받는 프리 플라이트 OPTIONS 호출을 수행합니다.

OPTIONS /signup HTTP/1.1 
Host: localhost:40000 
Access-Control-Request-Method: POST 
Origin: http://localhost:34001 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36 
Access-Control-Request-Headers: accept, content-type 
Accept: */* 
Referer: http://localhost:34001/signup 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: en-US,en;q=0.8 

를이 응답을 얻을 : 나는 찰스 네트워크 디버거를 사용하는 경우

, 나는 파이어 폭스가 이러한 헤더를 보내기를 참조하십시오

HTTP/1.1 200 OK 
Date: Sun, 13 Jul 2014 22:42:58 GMT 
Access-Control-Allow-Origin: http://localhost:34001 
Access-Control-Allow-Methods: DELETE, GET, POST, PUT 
Content-Type: application/octet-stream;charset=ISO-8859-1 
Content-Length: 18 
Server: Jetty(7.x.y-SNAPSHOT) 

preflight complete 

나는 그 응답에서 오는 아무 생각이 없습니다. 내 전체 프로젝트에서이 작업을 수행하는 경우 :

grep -iR "preflight complete" * 

"프리 플라이트 완료"라는 문구는 내 코드가 어디에 나타나지 않습니다. 그렇다면이 응답은 어디서 오는 것입니까? 그리고 CURL에서 전화를 걸 때와 동일한 경로에서 FireFox와 Chrome이 종료되지 않는 이유는 무엇입니까?

업데이트 : 마침내 대답을 찾았습니다.

나는 CORS을 해결하려고 할 몇 시간 동안 약 탈곡, 그리고 다른 많은 실험과 중,이 미들웨어 적용 :

https://github.com/r0man/ring-cors

및 헤더 내가 다시 전송 된 것을 오버라이드합니다. 이 오버라이드가 Ajax 요청에만 적용되고 컬 요청에는 해당되지 않는 이유가 궁금합니다. 어쩌면 링 - 코 (ring-cors)에 넣은 마술 r0man 일 수도 있습니다.어느 쪽이든, 나는 그것을 지웠고 지금 나는 되돌려 보내는 머리글을 보았다.

답변

4

두 가지 요청을 처리해야합니다. 첫 번째 옵션은 옵션이고 두 번째 요청은 게시물입니다. 운 좋게도 누군가 쉽게이 프레임 워크를 작성했습니다 (https://github.com/r0man/ring-cors).

당신이 링 고르를 사용하려는 경우, 당신은 모든 당신의 경로를 포장 할 수 있습니다

다음
(def app 
    (-> (handler/api app-routes) 
     (wrap-cors :access-control-allow-origin #"yoursite" 
       :access-control-allow-methods [:get :put :post] 
       :access-control-allow-headers ["Content-Type"]))) 
+0

이 내 솔루션을 알아내는 데 도움 것입니다 : https://groups.google.com/forum/ #! topic/luminusweb/8pKnjIR5eDA – Goose3gg

+0

고맙습니다. – cerhovice

관련 문제