2017-12-07 2 views
3

저는 웹 프로그래밍에 익숙하지 않으므로 나와 함께 곰이 있습니다. 저는 파이썬 플라스크에 간단한 REST API를 만들고 아파치 2.4로 호스팅하고 있습니다. 나는 그것을 cURL을 통해 테스트했으며 작동한다. 이제 jQuery와 웹 인터페이스를 통해 액세스하려고합니다.크로스 도메인 REST POST는 프리 플라이트 확인을하지만 수행하지 않습니다.

REST API는 http://api.localhost이고 액세스하는 웹 사이트는 http://localhost입니다.

나는 시도하고 POST는 다음과 같습니다 어떻게 사용하고 코드 :

$.ajax({ 
     type: 'POST', 
     url: 'http://api.localhost/auth', 
     data: '{"username":"user1", "password":"abcxyz"}', 
     success: function(data) { console.log(data); alert('data: ' + data); }, 
     contentType: "application/json", 
     dataType: 'json' 
    }); 

그러나, 성공 기능이 실행되지 않는 것 같습니다. dev 콘솔 (f12)에서 보면 해당 URL에 대한 POST 대신 OPTIONS HTTP 요청이 생성되었음을 알 수 있습니다. 나의 이해는 CORS (Cross-Origin Resource Sharing) 프리 플라이트 검사로, localhost가 api.localhost에 액세스 할 수 있는지 확인하는 것입니다.

나는 api.localhost 내 아파치 설정에 다음 줄을 추가했습니다 :

Header always set Access-Control-Allow-Origin "*" 
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS" 

그것은 OPTIONS 요청이 200 (및 다른 데이터)를 반환하기 때문에로 일하게 될 것으로 보인다. 그러나 후속 조치는 없습니다. 내 이해는 서버가 api.localhost에 POST 할 사람이 아무 문제가 없다고 말하고 있기 때문에 다음에 POST를 수행해야하지만 그렇지 않습니다. 여기

Host: api.localhost 
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 
Firefox/52.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 
Access-Control-Request-Method: POST 
Access-Control-Request-Headers: content-type 
Origin: http://localhost 
Connection: keep-alive 
Cache-Control: max-age=0 

이 (상태 (200)를 기억) 같은 요청에 대한 응답 헤더입니다 :

Access-Control-Allow-Methods: POST, GET, OPTIONS 
Access-Control-Allow-Origin: * 
Allow: POST, OPTIONS 
Connection: Keep-Alive 
Content-Encoding: gzip 
Content-Length: 20 
Content-Type: text/html; charset=utf-8 
Date: Thu, 07 Dec 2017 00:17:08 GMT 
Keep-Alive: timeout=5, max=100 
Server: Apache/2.4.29 (Debian) 
Vary: Accept-Encoding 

당신은 서버가 말하고있는 것을 볼 수 있습니다 여기에

는 프리 플라이트 검사 요청 헤더입니다 모든 도메인이 괜찮 으면 (*) POST가 정상입니다. 그러나 후속 POST가 없습니다. 내가 뭘 놓치고 있니?

감사합니다.

+1

'' '' '을' 'http : // localhost' '로 변경하고 아약스 요청에 오류 처리기를 추가하십시오. – charlietfl

답변

2

http://api.localhost/authAccess-Control-Allow-Headers: content-type으로 보내야합니다.

는 아파치 설정에 그래서, 당신은 또한이를 추가해야합니다

프론트 엔드 코드의 contentType: "application/json" 부분은 요청에 Content-Type: application/json 헤더를 추가하기 때문에 필요한입니다
Header always set Access-Control-Allow-Headers "content-type" 

하고 Content-Type 요청 헤더의 모든 값 text/plain, application/x-www-form-urlencoded 또는 multipart/form-data 이외의 경우 브라우저가 CORS 프리 플라이트 OPTIONS 요청을 보내도록 트리거합니다. 당신이있는 경우

그래서 당신의 http://api.localhost/auth 서버는 프리 플라이트의 성공 원인, 그래서 브라우저가 프론트 엔드 코드에서 POST 요청을로 이동하게한다 Access-Control-Allow-Headers: content-type 응답 헤더를 다시 보냅니다.

+0

모든 단일 요청에 대해 프리 플라이트를 수행하는 것처럼 보입니다. 요청 건수가 두 배로 늘어날 것입니다. 그 주위에 어떤 방법이 있습니까? – Dave

+1

Apache 서버가 Access Control Max-Age 응답 헤더를 보내도록 설정할 수 있습니다.이 응답 헤더는 브라우저에 OPTIONS 응답을 캐시하도록 지시합니다. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age.하지만 Chrome을 600으로 설정하면 (즉, Chrome에서는 OPTIONS 응답이 10 초 이상 캐시되지 않을 수 있기 때문에 600 (= 10 분) 이상으로 설정할 필요가 없을 것입니다. 의사록). – sideshowbarker

+0

굉장합니다. 감사. 심지어 5 초는 거대합니다. 페이지가 처음로드 될 때 10 개의 메소드를 요청한다고 가정 해 보겠습니다. 그것은 20 개의 요청을 생성 할 것이지만, 심지어 5 초 캐시를 사용하면 11까지 줄일 수 있습니다. – Dave

관련 문제