Heroku의 Express / Node.js 애플리케이션에 대한 CORS REST 요청 허용


97

Chrome의 js 콘솔 및 URL 표시 줄 등의 요청에 대해 작동하는 node.js 용 익스프레스 프레임 워크에 REST API를 작성했습니다. 이제 다른 앱의 요청에 대해 작동하도록 노력하고 있습니다. 도메인 (CORS).

자바 스크립트 프런트 엔드에 의해 자동으로 생성되는 첫 번째 요청은 / api / search? uri =에 대한 것이며 "프리 플라이트"OPTIONS 요청에서 실패한 것으로 보입니다.

내 익스프레스 앱에서 다음을 사용하여 CORS 헤더를 추가하고 있습니다.

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');

    // intercept OPTIONS method
    if ('OPTIONS' == req.method) {
      res.send(200);
    }
    else {
      next();
    }
};

과:

app.configure(function () {
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(allowCrossDomain);
  app.use(express.static(path.join(application_root, "public")));
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

Chrome 콘솔에서 다음 헤더를 얻습니다.

요청 URL : http : //furious-night-5419.herokuapp.com/api/search? uri = http % 3A % 2F % 2Flocalhost % 3A5000 % 2Fcollections % 2F1 % 2Fdocuments % 2F1

요청 방법 : 옵션

상태 코드 : 200 OK

요청 헤더

Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:origin, x-annotator-auth-token, accept
Access-Control-Request-Method:GET
Connection:keep-alive
Host:furious-night-5419.herokuapp.com
Origin:http://localhost:5000
Referer:http://localhost:5000/collections/1/documents/1
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5

쿼리 문자열 매개 변수

uri:http://localhost:5000/collections/1/documents/1

응답 헤더

Allow:GET
Connection:keep-alive
Content-Length:3
Content-Type:text/html; charset=utf-8
X-Powered-By:Express

API 애플리케이션에서 전송되는 적절한 헤더가없는 것처럼 보입니까?

감사.


내가 작성하지 않은 코드에서이 오류가 발생하지만 OPTIONS메서드 에 대한 처리기가 필요하다는 것을 이해하지 못합니다 . 누군가 방법을 POST모두 처리하는 대신 방법 만 처리하지 않는 이유를 이해하도록 도와 주 시겠습니까? POST OPTIONS
Ulysses Alves

도 포함 할 수 있습니다 PATCH당신이 그것을 사용하는 대신의 경우 PUT자원 업데이트 할
대니

답변:


66

깨끗한 ExpressJS 앱에서 코드를 확인했는데 제대로 작동합니다.

app.use(allowCrossDomain)구성 기능의 맨 위로 이동하십시오 .


8
그 이유는 app.use(app.router);Cheers 전에 정의해야하기 때문입니다 !
Michal

제 경우에는 req.method == 'OPTIONS'일 때 res.send (200)를 다시 보낸 후 다음 POST가 호출되지 않습니다. 나는 다른 것을 놓치고 있습니까?
Aldo

2Aldo : 코드가 필요합니다. 헤더를 잊으 셨나요? 서버가 preflight OPTIONS 요청을 올바르게 제공 한 후 클라이언트가 POST를 보내지 않는 경우 개발자 도구 콘솔을 확인하십시오. WebKit은 이러한 종류의 오류를 웹 검사기의 콘솔에 기록합니다.
Olegas 2012

1
@ConnorLeech 아주 좋습니다. 위와 같이 allowCrossDomain 접근 방식을 수행하고 있었고 모든 헤더 관리를 처리하는 데 지쳤습니다. 또한-우리는 dev에 CORS 만 필요했기 때문에 무슨 일이 일어나고 있는지 알아내는 데 너무 많은 사이클을 할애하는 것은 말이되지 않았습니다. 이것을 쉽게 허용하기위한 node.js 지원이있어서 다행입니다.
Steven

1
나는 ... 당신이 대답으로 당신의 코멘트를 추가해야한다고 생각 @ConnorLeech 것은 치료처럼 작동하고, 그것의 좋은 간단한
drmrbrewer

4

자격 증명으로 쿠키를 지원하려면이 줄이 필요합니다. xhr.withCredentials = true;

mdn docs xhr.withCredentials

Express Server에서이 블록을 다른 모든 블록 앞에 추가하십시오.

`app.all('*', function(req, res, next) {
     var origin = req.get('origin'); 
     res.header('Access-Control-Allow-Origin', origin);
     res.header("Access-Control-Allow-Headers", "X-Requested-With");
     res.header('Access-Control-Allow-Headers', 'Content-Type');
     next();
});`

4

나는 이것을 대답 으로 추가하고있다. 왜냐하면 원래 포스트가 코멘트로 씌여 졌기 때문에 내가이 페이지를 처음봤을 때 진정으로 당신이 간과했기 때문이다.

@ConnorLeech 위의 허용 대답에 자신의 의견에서 지적 하듯이, 당연한라는 매우 편리한 NPM 패키지가 고르 . 사용은 var cors = require('cors'); app.use(cors());(다시 말하지만 Leech의 답변에서 설명 함)만큼 간단하며 문서에 설명 된대로 더 엄격하고 구성 가능한 방식으로 적용 할 수도 있습니다. .

위에서 언급 한 원본 댓글이 2014 년에 작성되었다는 점도 지적 할 가치가 있습니다. 이제 2019 년이고 npm 패키지의 github 페이지를 보면 최근에 9 일 전에 리포지토리가 업데이트되었습니다.


0

이 질문을 탐색하는 대부분의 사람들에게는 해당되지 않지만 정확히 동일한 문제가 있었고 해결책은 다음과 관련이 없습니다. CORS .

JSON 웹 토큰 시크릿 string이 환경 변수에 정의되지 않았으므로 토큰에 서명 할 수 없습니다. 이로 인해 POST시간 제한을 받고 503오류를 반환하기 위해 토큰을 확인하거나 서명하는 데 의존 하는 모든 요청 이 발생 하여 브라우저에 문제가 있음을 알립니다.CORS . Heroku에 환경 변수를 추가하면 문제가 해결되었습니다.

누군가에게 도움이되기를 바랍니다.


네 그게 문제였습니다. 문제를 어떻게 해결했는지 좀 더 구체적으로 말씀해 주시겠습니까? 나는 아직 개발 중이며 노드 cors 패키지가있는 Express.js에서 실행 중입니다.
Alan

@alan 내 응용 프로그램에서 토큰을 확인하는 약속을 사용했습니다. JWT 비밀이 정의되지 않은 경우 약속이 해결되지 않는 방법은 다음과 같습니다 . 추가 참조가 필요한 경우 사용 했던 코드 는 다음과 같습니다 .
CatBrownie

응답 해 주셔서 감사합니다. 코드를 살펴 보겠습니다. 비밀로 두 번째 개인 키에 대해 이야기하고 있다고 가정합니다. oauth2를 사용하고 있습니다.
Alan

약속이 실패하면이 잘못된 오류가 발생할 것이라고 덧붙일 것입니다! 사용중인 Node 버전에 대해 명시해야했습니다. 그렇지 않으면 데이터베이스 호출 (mongo)이 단순히 중단되고 브라우저가 나에게 말할 수있는 유일한 것은 503과 Cors 관련 어리 석음이었습니다. 이 오류는 내가 app.use(cors());가던 중 가장 오랫동안 나를 혼란스럽게 만들었습니다 .
alphanumeric0101

0

여기에 이미지 설명 입력

아래 단계를 따르십시오.

npm 설치 cors --save

루트 js 파일 내부 :

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