2017-09-09 11 views
3

를 restify하는 Axios의/반응에서 JSON과 POST 요청을 할 수 없습니다. 나는 안드로이드 애플리케이션, Python 스크립트에서 서버를 호출했고 단순히 curl을 사용하여 테스트했다. 전혀 문제 없습니다. 산뜻한!내가이처럼 설정 restify이 서버

그러나 지금은 React가 포함 된 웹 응용 프로그램을 구현했으며 axios 패키지를 사용하여 restify API에 요청하고 싶습니다. GET 요청은 문제가 없으므로 URL 등에서 오타를 제외합니다.

그러나 다음과 같은 POST 요청이 작동하지 않습니다 : 나는 브라우저 개발자 도구를 사용하여 검사 할 때, 나는 브라우저가 OPTIONS 요청 (안 POST)를 만들려고 노력하는 것을 볼 수 있습니다

var data = {"test": "hello"}; 
axios.post("http://.../api/v1/message/question/public/add", data) 
    .then(function (response) { 
    console.log("Test question sent!"); 
    }) 
    .catch(function (error) { 
    console.log(error); 
    }); 

해당 URL에. 나는 브라우저가 "프리 플라이트 요청"을하고 있기 때문에 내가 읽은 것으로부터 가정합니다. 문제는 405 Method Not Allowed 오류가 발생합니다.

Request URL: http://.../api/v1/message/question/public/add 
Request method: OPTIONS 
Remote address: ... 
Status code: 405 Method Not Allowed 

Response headers (178 B)  
    Server: restify 
    Allow: POST 
    Content-Type: application/json 
    Content-Length: 62 
    Date: Sat, 09 Sep 2017 08:16:32 GMT 
    Connection: keep-alive 
Request headers (485 B) 
    Host: ... 
    User-Agent: Mozilla/5.0 (X11; Ubuntu; Linu…) Gecko/20100101 Firefox/55.0 
    Accept: text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8 
    Accept-Language: en-ZA,en-GB;q=0.8,en-US;q=0.5,en;q=0.3 
    Accept-Encoding: gzip, deflate 
    Access-Control-Request-Method: POST 
    Access-Control-Request-Headers: content-type 
    Origin: http://... 
    DNT: 1 
    Connection: keep-alive 

왜 그런가요? 나는 모두 Access-Control-Allow-Methods을 복구 할 수 있습니다. POST 요청을 제외한 모든 요청이 브라우저에서만 제공됩니다 (React Web 앱 사용). 나는 그것이 OPTIONS 요청 때문이라고 생각하지만, 어떻게 처리해야할지 모르겠습니다.

그런데 JSON.stringify(data)으로, POST 요청이 처리되지만 API는 Json과 문자열이 필요하지 않습니다. 그리고 다른 모든 수단으로는 완벽하게 작동하기 때문에이 문제를 해결하기 위해 코드를 변경하는 것을 원하지 않습니다.

나는이 회선을 사용하는 경우 [1], 나는 다음과 같은 오류 얻을 :

server.opts(/\.*/, function (req, res, next) { 
    res.send(200); 
    next(); 
}); 

또 다른 : AssertionError [ERR_ASSERTION]: acceptable ([string]) is required at Object.acceptParser (/home/bob/node_modules/restify/lib/plugins/accept.js:30:12)

답변

1

서버는 기본적으로 OPTIONS을 허용하지 않는 경우, 당신은 명시 적 처리기를 추가 할 수 있습니다

res.setHeader('Access-Control-Allow-Headers', '*'); 
res.setHeader('Access-Control-Allow-Methods', '*'); 

* 와일드 카드 값 일 : 가능한 문제는 효과가 다음과 같은 헤더 의도가없는 것입니다 브라우저는 스펙에 의해 허용되지만 브라우저는 아직 지원하지 않습니다. 그래서 대신 IS 무엇을해야하는지, 명시 적으로 그 값을 지정하는 방법과 헤더 수 있도록 :

CORS 프리 플라이트 OPTIONS 요청에 대해 표시된 요청 헤더가 있기 때문이다
res.setHeader('Access-Control-Allow-Headers', 'content-type'); 
res.setHeader('Access-Control-Allow-Methods', 'POST'); 

이 :

Access-Control-Request-Method: POST 
Access-Control-Request-Headers: content-type 
Origin: http://... 

그리고 해당 요청 헤더가 나타내는 것, 브라우저가 서버에 요청하는 것입니다. 이 원점에서 실행중인 일부 코드는 서버에 POST 요청을 작성하여 요청에 특정 Content-Type을 추가하려고합니다. 자신의 을 추가하는 POST 요청을 수신해도 괜찮습니까?

은 그래서 프리 플라이트 OPTIONS 요청에 대한 응답으로, 브라우저는 명시 적으로 명시 적으로 Content-Type을 허용하는 Access-Control-Allow-Headers 응답 헤더와 함께 POST을 허용하는 Access-Control-Allow-Methods 응답 헤더를받을 것으로 기대하고있다.

+0

해결책을 찾았습니다. 내 대답을 참조하십시오. 와일드 카드 대신 명시 적으로 설정을 시도했지만 아무 것도 작동하지 않았습니다. 'Access-Control-Allow-Methods'에'OPTIONS'이 있었는지 여부는 아무런 차이가 없었습니다. 나는 당신의 해결책을 빨리 시험해 보았다. 'OPTIONS' 요청은 지금 200을 리턴하지만, POST가 끝나지 않습니다. 다시 말하지만, 와일드 카드를 사용하는지 여부는 독립적입니다. 나는 아직도 somehing을 놓치고있는 I 'm를 추측한다. – Christian

+0

귀하의 회신은 확실히 올바른 방향으로 진행되었으며, 결국 귀하의 평신도 설명이 매우 유용하다는 것을 알게되었습니다. 그것은 제 배경에서 멀리 떨어져 있습니다. 따라서 내 upvote. 매우 감사! – Christian

1

두 시간이 더 지난 후에 나는 결국 solution을 발견했습니다. 다음과 같이 내 restify 서버 코드를 변경했습니다 :

var restify = require("restify"); 
var corsMiddleware = require('restify-cors-middleware') 

var cors = corsMiddleware({ 
    preflightMaxAge: 5, //Optional 
    origins: ['*'], 
    allowHeaders: ['API-Token'], 
    exposeHeaders: ['API-Token-Expiry'] 
}); 


// WITHOUT HTTPS 
const server = restify.createServer(); 

server.pre(cors.preflight); 
server.use(cors.actual); 
... 
(rest is the same as above) 

는 솔직히 말해서, 나는 그것이 실제 무엇을 진짜 생각을했습니다 없습니다. 그러나 그것은 효과가 있습니다. 그리고 그것은 제가 이미 오늘 너무 많은 에너지를 소비하게 만듭니다. 나는 그것이 어떤 시점에서 다른 사람들에게 도움이되기를 바랍니다. 모든 것이 최근에 변경된 것 같습니다. restify.