「Access-Control-Allow-Origin」なし-ノード/ Apacheポートの問題


260

Node / Expressを使用して小さなAPIを作成し、Angularjsを使用してデータをプルしようとしましたが、htmlページがlocalhost:8888のApacheの下で実行されており、ノードAPIがポート3000でリッスンしているため、「アクセス制御なし」になります。 Allow-Origin '。node-http-proxyApache を使用してVhosts を試してみました が、あまり成功していません。以下の完全なエラーとコードを参照してください。

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>

回答:


622

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 2013年

1
@jvandemo do app to get the app.get( '/'、function(req、res)to ... function(req、res、next)?
Sangram Singh

10
あなたは今、私の好きな人です。ありがとうございました。私のような初心者向けにルートが定義される前に、このコードを実行する必要があるというメモを追加できますか?
gegillam 2016

1
リクエストモジュールを使用しながらこれを機能させるにはどうすればよいですか?
Rohit Tigga 16年

2
私の場合はうまくいきませんでした。それでもこのエラーが発生する:「プリフライト要求への応答がアクセス制御チェックに合格しません:要求されたリソースに 'Access-Control-Allow-Origin'ヘッダーがありません。そのため、Origin ' abc.xyz.net:212 'は許可されませんアクセス。応答のHTTPステータスコードは500でした。」
user1451111 2018

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

起源が異なるさまざまなメソッドを必要とする私のユースケースを非常にうまく処理した甘い小さなライブラリ...そしてそれを見る次の人にとってコードの疲労が少ない。
カイルベイカー

6
ありがとう、enable-corsのようにapp.use(cors({origin: '*'}));私のために働いた。
ダニアルク2017

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)?」と同じですか?
Rune Jeppesen 2016

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 2017

おかげで;)正常に動作します
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

NODEJ Restful APIのapp.jsに次のコードを追加して、Angle 6またはその他のフレームワークでの「Access-Control-Allow-Origin」エラーを回避します

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

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

コマンドプロンプトでこのコマンドを入力する場合は、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 &"

2番目のオプション

open(1)を使用してフラグを追加することができます:open -a 'Google Chrome' --args --allow-file-access-from-files


MACではどうですか?Chrome.exe --allow-file-access-from-files
user1336103 '19

/アプリケーション/グーグル\ Chrome.app/Contents/MacOS/Google \クローム--allow-ファイル・アクセスから、ファイルが開いているクロムに管理するが、メッセージはまだのXMLHttpRequestをロードできません」と表示されるのlocalhost:3000を。起源はlocalhost:8888ですAccess-Control-Allow-Originでは許可されていません。 "
user1336103 '19

+1「open」を使用してMacオプションでこれが動作することを確認できます。ローカルのJSONファイルにアクセスする完全にダウンロードされたサイトをテストするだけなので、私の場合は少し異なります。
2013

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.