web-dev-qa-db-ja.com

'Access-Control-Allow-Origin'がない - ノード/ Apacheポートの問題

node/Expressを使って小さなAPIを作成し、Angularjsを使ってデータを取得しようとしていますが、私のHTMLページはApacheのlocalhost:8888で実行されているので、ノードAPIはポート3000で待機しています。 Allow-Origin '。私はnode-http-proxyとVhosts Apacheを使ってみましたが、あまり成功しませんでした。以下の完全なエラーとコードを見てください。

"XMLHttpRequestはlocalhost:3000をロードできません。要求されたリソースに 'Access-Control-Allow-Origin'ヘッダがありません。そのため、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 code
    angular.module('contractorsApp', [])
    .controller('ContractorsCtrl', function($scope, $http,$routeParams) {

   $http.get('localhost:3000').success(function(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>
218
user1336103

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();
});

それが役立つことを願っています!

545
jvandemo

あなたがもっと短いものを好む場合には、あなたはExpress.jsで利用可能なcorsと呼ばれるプラグインを使用することができます。

この特定のケースでは、使い方は簡単です。

var cors = require('cors');

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

別の方法は、あなたのルートに単にヘッダを追加することです。

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:)');
});
27
Asaf Hananel

トップの答え は私にはうまくいきました。ただし、私は複数のドメインをホワイトリストに登録する必要がありました。

また、トップアンサーはOPTIONSリクエストがミドルウェアによって処理されず、あなたがそれを自動的に得ないという事実に悩まされています。

allowed_originsでは複数のドメインを指定することができないため、ホワイトリストに登録されたドメインをExpress構成のAccess-Control-Allow-Originとして格納し、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);
});
14
Dan Abramov

回答コードは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();
});
12
Vicheanak

プロジェクトにCors依存関係をインストールします。

npm i --save cors

サーバー構成ファイルに以下を追加します。

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

それは2.8.4コアのバージョンで私のために動作します。

6
monikaja

これは私のために働きました。

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

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

ニーズに合わせて*を変更できます。これが役立つことを願っています。

3
dmx
//Add following code in app.js of NODEJ Restful api to avoid "Access-Control-Allow-Origin" error in angular 6 or any other framework

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
}));
2
Ezhil Arasan
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
Wiki

あなたは "$ http.jsonp"を使うことができます

OR

以下はローカルテスト用のクロムの回避策です。

次のコマンドであなたのクロムを開く必要があります。 (ウィンドウ+ Rを押す)

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

注意:あなたのクロムは開いてはいけません。このコマンドを実行すると、chromeは自動的に開きます。

コマンドプロンプトでこのコマンドを入力している場合は、クロムインストールディレクトリを選択してからこのコマンドを使用します。

以下の「--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

1
JQuery Guru

こんにちは、これはフロントエンドとバックエンドが異なるポートで実行されているときに発生します。 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

0
Karthik S Kumar
/**
 * 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.
0
Luton Datta