[node.js] 브라우저가 CORS 헤더를 OPTIONS 라우트에 추가 할 수없는 이유는 무엇입니까?

Express.js 웹 프레임 워크를 사용하는 Node.js 응용 프로그램에서 CORS를 지원하려고합니다. 나는 읽고 구글 그룹 토론 이 처리하는 방법과 CORS 작품에 대한 몇 가지 기사를 읽는 방법에 대한합니다. 먼저, 이것을했습니다 (코드는 CoffeeScript 구문으로 작성되었습니다).

app.options "*", (req, res) ->
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  # try: 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Methods', 'GET, OPTIONS'
  # try: 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

작동하지 않는 것 같습니다. 내 브라우저 (Chrome)가 초기 OPTIONS 요청을 보내지 않는 것 같습니다. 리소스에 대한 블록을 방금 업데이트했을 때 교차 출처 GET 요청을 제출해야합니다.

app.get "/somethingelse", (req, res) ->
  # ...
  res.header 'Access-Control-Allow-Origin', '*'
  res.header 'Access-Control-Allow-Credentials', true
  res.header 'Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS'
  res.header 'Access-Control-Allow-Headers', 'Content-Type'
  # ...

작동합니다 (Chrome에서). 이것은 Safari에서도 작동합니다.

나는 그것을 읽었습니다 …

CORS를 구현하는 브라우저에서 각 교차 출처 GET 또는 POST 요청 앞에 GET 또는 POST가 올바른지 확인하는 OPTIONS 요청이옵니다.

그래서 내 주요 질문은, 어떻게 이런 일이 일어나지 않는 것입니까? 왜 app.options 블록이 호출되지 않습니까? 기본 app.get 블록에서 헤더를 설정해야하는 이유는 무엇입니까?



답변

주요 질문에 대답하기 위해 POST 또는 GET에 단순하지 않은 컨텐츠 나 헤더가있는 경우 CORS 스펙은 POST 또는 GET 앞에 OPTIONS 호출 만 필요합니다.

CORS 비행 전 요청 (OPTIONS 호출)이 필요한 컨텐츠 유형 은 다음을 제외한 모든 컨텐츠 유형입니다 .

  1. application/x-www-form-urlencoded
  2. multipart/form-data
  3. text/plain

위에 나열된 것 이외의 다른 컨텐츠 유형은 비행 전 요청을 트리거합니다.

헤더 와 관련하여 다음제외한 모든 요청 헤더 는 비행 전 요청을 트리거합니다.

  1. Accept
  2. Accept-Language
  3. Content-Language
  4. Content-Type
  5. DPR
  6. Save-Data
  7. Viewport-Width
  8. Width

다른 요청 헤더는 비행 전 요청을 트리거합니다.

따라서 :과 같은 사용자 지정 헤더를 추가하면 x-Trigger: CORS비행 전 요청이 트리거되고 OPTIONS 블록에 도달합니다.

MDN 웹 API 참조-CORS 사전 요청을 참조 하십시오.


답변

가장 쉬운 방법은 node.js 패키지 cors 를 사용하는 것 입니다. 가장 간단한 사용법은 다음과 같습니다.

var cors = require('cors')

var app = express()
app.use(cors())

물론 필요에 따라 동작을 구성하는 방법은 여러 가지가 있습니다. 위에 링크 된 페이지는 여러 가지 예를 보여줍니다.


답변

다음 일치하는 경로로 제어를 전달하십시오. Express가 app.get 경로와 먼저 일치하는 경우이를 수행하지 않으면 옵션 경로로 계속 진행되지 않습니다 (다음 사용 참고) .

app.get('somethingelse', function(req, res, next) {
    //..set headers etc.

    next();
});

CORS를 구성하는 측면에서, 나는 그것을 잘 작동하는 미들웨어에 넣었습니다.

//CORS middleware
var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'example.com');
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');

    next();
}

//...
app.configure(function() {
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({ secret: 'cool beans' }));
    app.use(express.methodOverride());
    app.use(allowCrossDomain);
    app.use(app.router);
    app.use(express.static(__dirname + '/public'));
});


답변

라우팅과 동일한 아이디어를 유지합니다. 이 코드를 사용합니다 :

app.all('/*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  next();
});

http://enable-cors.org/server_expressjs.html 예제 와 유사


답변

하다

npm install cors --save

요청이 진행되는 기본 파일 에이 줄을 추가하십시오 (라우트 전에 유지).

const cors = require('cors');
const express = require('express');
let app = express();
app.use(cors());
app.options('*', cors());


답변

Express 또는 Connect에 적합한보다 완벽한 미들웨어를 만들었습니다. OPTIONS프리 플라이트 검사 요청을 지원 합니다. 그것은 CORS가 무엇이든 접근 할 수 있도록 허용 할 것입니다.

app.use(function(req, res, next) {
    var oneof = false;
    if(req.headers.origin) {
        res.header('Access-Control-Allow-Origin', req.headers.origin);
        oneof = true;
    }
    if(req.headers['access-control-request-method']) {
        res.header('Access-Control-Allow-Methods', req.headers['access-control-request-method']);
        oneof = true;
    }
    if(req.headers['access-control-request-headers']) {
        res.header('Access-Control-Allow-Headers', req.headers['access-control-request-headers']);
        oneof = true;
    }
    if(oneof) {
        res.header('Access-Control-Max-Age', 60 * 60 * 24 * 365);
    }

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


답변

expressjs의 cors 모듈을 설치하십시오. 이 단계를 수행 할 수 있습니다>

설치

npm install cors

간단한 사용법 (모든 CORS 요청 사용)

var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());

자세한 내용은 https://github.com/expressjs/cors참조하십시오.