'액세스 제어 허용 출처'없음-노드 / 아파치 포트 문제


260

Node / Express를 사용하여 작은 API를 만들고 Angularjs를 사용하여 데이터를 가져 오려고했지만 html 페이지가 localhost : 8888에서 아파치로 실행 중이고 노드 API가 포트 3000에서 수신 대기 중이므로 No 'Access-Control- 허용-원본. node-http-proxyApache를 사용 하고 Vhosts Apache를 사용했지만 성공하지 못했습니다. 아래의 전체 오류 및 코드를 참조하십시오.

XMLHttpRequest가 localhost : 3000을로드 할 수 없습니다. 요청 된 리소스에 'Access-Control-Allow-Origin'헤더가 없습니다. 따라서 'localhost : 8888'은 액세스 할 수 없습니다. "

// Api Using Node/Express    
var express = require('express');
var app = express();
var contractors = [
    {   
     "id": "1", 
        "name": "Joe Blogg",
        "Weeks": 3,
        "Photo": "1.png"
    }
];

app.use(express.bodyParser());

app.get('/', function(req, res) {
  res.json(contractors);
});
app.listen(process.env.PORT || 3000);
console.log('Server is running on Port 3000')

각도 코드

angular.module('contractorsApp', [])
.controller('ContractorsCtrl', function($scope, $http,$routeParams) {

   $http.get('localhost:3000').then(function(response) {
       var data = response.data;
       $scope.contractors = data;
   })

HTML

<body ng-app="contractorsApp">
    <div ng-controller="ContractorsCtrl"> 
        <ul>
            <li ng-repeat="person in contractors">{{person.name}}</li>
        </ul>
    </div>
</body>

답변:


621

NodeJS / Express 앱에 다음 미들웨어를 추가해보십시오 (편의를 위해 의견을 추가했습니다).

// Add headers
app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});

희망이 도움이됩니다!


2
그것이 어디로 가는지 정확하게 지정할 수 있습니까? 서버에 다음 코드가 있습니다. 이 후 바로 가나 요? var app = require ( 'express') (), server = require ( 'http'). createServer (app), io = require ( 'socket.io'). listen (server), request = require ( "request") , url = require ( "url"); server.listen (6969); // 여기가요? 새로운 줄에?
Art Geigel

1
@jvandemo app.get ( '/', function (req, res)를 ... function (req, res, next)로 변경해야합니까?
Sangram Singh

10
당신은 지금까지 내가 가장 좋아하는 사람입니다. 감사합니다. 나 같은 멍청한 놈에 대한 경로가 정의되기 전에이 코드가 발생해야한다는 메모를 추가 할 수 있습니까?
gegillam

1
요청 모듈을 사용하는 동안이 작업을 수행하는 방법은 무엇입니까?
Rohit Tigga

2
내 경우에는 작동하지 않았습니다. 그래도이 오류가 계속 발생합니다. "사전 비행 요청에 대한 응답이 액세스 제어 확인을 통과하지 못합니다. 요청 된 리소스에 'Access-Control-Allow-Origin'헤더가 없습니다. 따라서 원본 ' abc.xyz.net:212 '는 허용되지 않습니다. 응답에 HTTP 상태 코드 500이 있습니다. "
user1451111

96

더 짧은 것을 선호하는 경우 받아 들일 수있는 대답은 괜찮습니다 .Express.js에 사용할 수있는 cors 라는 플러그인을 사용할 수 있습니다

이 특별한 경우에 사용하는 것이 간단합니다.

var cors = require('cors');

// use it before all route definitions
app.use(cors({origin: 'http://localhost:8888'}));

3
나는 {origin: 'null'}그것을 작동시키기 위해 사용해야 했다 null.
Ricardo Cruz

2
왜 바퀴를 재발 명합니까? 저는 코드 스 니펫과 비교하여 항상 패키지 솔루션을 제공합니다
Pierre

다른 출처에서 다른 방법을 원할 때 내 유스 케이스를 처리하는 달콤한 작은 라이브러리.
Kyle Baker

6
enable-cors에app.use(cors({origin: '*'})); 따라 감사 했습니다 .
danialk

2
더 잘 활용하기 위해 npm cors 페이지 를 살펴 보는 것이 좋습니다 . 그것은 나를 위해 매우 분명한 것을 만들었습니다 =).
13013SwagR

30

다른 방법은 단순히 헤더를 경로에 추가하는 것입니다.

router.get('/', function(req, res) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); // If needed
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); // If needed
    res.setHeader('Access-Control-Allow-Credentials', true); // If needed

    res.send('cors problem fixed:)');
});

8
)스마일의 나를 혼란스러워
diEcho

17

상단의 대답은 내가 허용 된 사이트 목록 개 이상의 도메인에 필요한 것을 제외하고, 나를 위해 벌금을했다.

또한 최고 답변은 OPTIONS요청이 미들웨어에 의해 처리되지 않고 자동으로 얻지 못한다 는 사실로 인해 어려움을 겪 습니다.

allowed_originsExpress 구성에서와 같이 화이트리스트 도메인을 저장 하고 둘 이상의 도메인을 지정할 수 없으므로 origin헤더 에 따라 올바른 도메인을 넣습니다 Access-Control-Allow-Origin.

내가 끝내었던 것은 다음과 같습니다.

var _ = require('underscore');

function allowCrossDomain(req, res, next) {
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');

  var origin = req.headers.origin;
  if (_.contains(app.get('allowed_origins'), origin)) {
    res.setHeader('Access-Control-Allow-Origin', origin);
  }

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

app.configure(function () {
  app.use(express.logger());
  app.use(express.bodyParser());
  app.use(allowCrossDomain);
});

이것이 'if (app.get ('allowed origins '). indexOf (origin)! ==-1)'과 동일합니까? '
룬 제 페슨

13

응답 코드는 localhost : 8888에만 허용됩니다. 이 코드는 프로덕션 또는 다른 서버 및 포트 이름에 배포 할 수 없습니다.

모든 소스에서 작동하게하려면 대신 다음을 사용하십시오.

// Add headers
app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', '*');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});

2
이것은 나를 위해 작동하지 않습니다! "*는 유효한 원점이 아닙니다". * 문자가 와일드 카드로 인식되지 않는 것 같습니다.
Francesco

그것은 나를 위해 작동합니다. 즉, 와일드 카드 '*'를 사용합니다. 크롬과 사파리 모두에서 작동합니다.
AnBisw

감사합니다;) 잘 작동
Mauro

9

프로젝트에 cors 종속성을 설치하십시오.

npm i --save cors

서버 구성 파일에 다음을 추가하십시오.

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

2.8.4 cors 버전으로 작동합니다.


"cors": "^2.8.5", "express": "^4.16.3",@ monikaja가 제안한 줄과 잘 작동합니다. 감사!
RamiroIsBack

이것이하는 일은 모든 출처 / 도메인이 일반적으로 원하지 않는 앱에 액세스 할 수 있도록하는 것입니다. 대신 허용 된 도메인 만 지정하십시오.
Lacho Tomov

7

이것은 나를 위해 일했습니다.

app.get('/', function (req, res) {

    res.header("Access-Control-Allow-Origin", "*");
    res.send('hello world')
})

필요에 따라 *를 변경할 수 있습니다. 이것이 도움이되기를 바랍니다.


7

안녕 이것은 프론트 엔드와 백엔드가 다른 포트에서 실행될 때 발생합니다. CORS 헤더가 없기 때문에 브라우저가 백엔드의 응답을 차단합니다. 해결책은 백엔드 요청에 CORS 헤더를 추가하는 것입니다. 가장 쉬운 방법은 cors npm 패키지를 사용하는 것입니다.

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

모든 요청에서 CORS 헤더를 사용할 수 있습니다. 자세한 내용은 cors 설명서를 참조하십시오.

https://www.npmjs.com/package/cors


3
app.all('*', function(req, res,next) {
    /**
     * Response settings
     * @type {Object}
     */
    var responseSettings = {
        "AccessControlAllowOrigin": req.headers.origin,
        "AccessControlAllowHeaders": "Content-Type,X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5,  Date, X-Api-Version, X-File-Name",
        "AccessControlAllowMethods": "POST, GET, PUT, DELETE, OPTIONS",
        "AccessControlAllowCredentials": true
    };

    /**
     * Headers
     */
    res.header("Access-Control-Allow-Credentials", responseSettings.AccessControlAllowCredentials);
    res.header("Access-Control-Allow-Origin",  responseSettings.AccessControlAllowOrigin);
    res.header("Access-Control-Allow-Headers", (req.headers['access-control-request-headers']) ? req.headers['access-control-request-headers'] : "x-requested-with");
    res.header("Access-Control-Allow-Methods", (req.headers['access-control-request-method']) ? req.headers['access-control-request-method'] : responseSettings.AccessControlAllowMethods);

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


});

2

각도 6 또는 다른 프레임 워크에서 "Access-Control-Allow-Origin"오류를 피하기 위해 NODEJ의 app.js에 다음 코드를 추가하십시오.

var express = require('express');
var app = express();

var cors = require('cors');
var bodyParser = require('body-parser');

//enables cors
app.use(cors({
  'allowedHeaders': ['sessionId', 'Content-Type'],
  'exposedHeaders': ['sessionId'],
  'origin': '*',
  'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
  'preflightContinue': false
}));

1

"$ http.jsonp"를 사용할 수 있습니다

또는

아래는 로컬 테스트를위한 크롬 해결 방법입니다.

다음 명령으로 크롬을 열어야합니다. (창 + R을 누름)

Chrome.exe --allow-file-access-from-files

참고 : 크롬이 열려 있지 않아야합니다. 이 명령을 실행하면 크롬이 자동으로 열립니다.

명령 프롬프트에이 명령을 입력 한 경우 크롬 설치 디렉토리를 선택한 다음이 명령을 사용하십시오.

"--allow-file-access-from-files"가있는 MAC에서 열린 크롬에 대한 스크립트 코드 아래

set chromePath to POSIX path of "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" 
set switch to " --allow-file-access-from-files"
do shell script (quoted form of chromePath) & switch & " > /dev/null 2>&1 &"

두 번째 옵션

open (1) 을 사용 하여 플래그를 추가 할 수 있습니다 . open -a 'Google Chrome'--args --allow-file-access-from-files


MAC은 어떻습니까? Chrome.exe-파일 접근 허용 파일
user1336103

/ 응용 프로그램 / 구글 \ Chrome.app/Contents/MacOS/Google \ 크롬 --allow는 파일 액세스-부터 파일이 열려 크롬으로 관리하지만, 메시지가 계속 XMLHttpRequest를로드 할 수 없습니다 "보여주는 로컬 호스트 : 3000 . 원산지는 로컬 호스트 : 8888 입니다 Access-Control-Allow-Origin에서는 허용되지 않습니다. "
user1336103

+1 '열기'를 사용하여 Mac 옵션에서 작동하는지 확인할 수 있습니다. 일부 로컬 JSON 파일에 액세스하는 완전히 다운로드 된 사이트를 테스트하기 때문에 제 경우가 약간 다릅니다.
spong

0

/**
 * Allow cross origin to access our /public directory from any site.
 * Make sure this header option is defined before defining of static path to /public directory
 */
expressApp.use('/public',function(req, res, next) {
    res.setHeader("Access-Control-Allow-Origin", "*");
    // Request headers you wish to allow
    res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    // Set to true if you need the website to include cookies in the requests sent
    res.setHeader('Access-Control-Allow-Credentials', true);
    // Pass to next layer of middleware
    next();
});


/**
 * Server is about set up. Now track for css/js/images request from the 
 * browser directly. Send static resources from "./public" directory. 
 */
expressApp.use('/public', express.static(path.join(__dirname, 'public')));
If you want to set Access-Control-Allow-Origin to a specific static directory you can set the following.

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