web-dev-qa-db-ja.com

Origin http:// localhostはAccess-Control-Allow-Originで許可されていません

私は、backbone.jsからnode.jsサーバーへのフェッチを試みています。ただし、コンソールに次のエラーが表示されます。

Origin http://localhost is not allowed by Access-Control-Allow-Origin.

Node.jsサーバーに次を追加しました。

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', "http://localhost");
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
};

app.configure(function() {
    app.use(allowCrossDomain);
});

しかし、それでも同じエラーが返されます。ただし、これが機能したとしても、理想的なソリューションとは思えません。世界中のユーザーがリクエストを送信できるようにしたいからです。

10
Willem Ellis

誰もがNodeアプリにアクセスできるようにしたい場合は、

res.header('Access-Control-Allow-Origin', "*")

これにより、任意のオリジンからのリクエストが許可されます。 CORS enable サイトには、さまざまなAccess-Control-Allowヘッダーとその使用方法に関する多くの情報があります。

Chromeを使用している場合は、 this localhostおよびAccess-Control-Allow-Originに関するバグバグをご覧ください。別の StackOverflowの質問 があり、問題の詳細を説明しています。

12
ryanday

ローカルホストでは、null Originを使用する必要があります。許可されたホストのリストを作成し、リクエストのHostヘッダーを確認することをお勧めします。リストに含まれている場合、ローカルホストによって

res.header('Access-Control-Allow-Origin', "null");

他のドメインによって

res.header('Access-Control-Allow-Origin', hostSentByTheRequestHeader);

リストに含まれていない場合は、サーバーのホスト名を送り返すので、ブラウザーはこれらの要求による応答を非表示にします。

Origin *を許可し、資格情報を許可することで、たとえば、ログインしているユーザーのプロファイルデータを盗むことができるため、これははるかに安全です。

そのため、次のように要約します。

if (reqHost in allowedHosts)
    if (reqHost == "http://localhost")
        res.header('Access-Control-Allow-Origin', "null");
    else
        res.header('Access-Control-Allow-Origin', reqHost);
else
    res.header('Access-Control-Allow-Origin', serverHost);

他の複数のドメインがページにアクセスできるようにする場合は、最も安全なソリューションです。 (node.jsでホストリクエストヘッダーとサーバーホストを取得する方法を理解できると思います。)

0
inf3rno

私が推測しているローカルホストへのフェッチ呼び出しをバックボーンコードと同じディレクトリのnode.jsによって実行している場合、それはおそらくhttp://localhost:3000またはそのようなもの。これはあなたのモデルでなければなりません:

var model = Backbone.Model.extend({
    url: '/item'
});

そして、node.jsで、次のようにその呼び出しを受け入れる必要があります。

app.get('/item', function(req, res){
    res.send('some info here');
});
0
Stevo Perisic

正しいヘッダーを設定する必要がある2つの呼び出しがあります。最初はプリフライトチェックがあるため、次のようなものが必要です...

app.get('/item', item.list);
app.options('/item', item.preflight);

そして、次の機能を持っています...

exports.list = function (req, res) {
Items.allItems(function (err, items) {
    ...
        res.header('Access-Control-Allow-Origin', "*");     // TODO - Make this more secure!!
        res.header('Access-Control-Allow-Methods', 'GET,PUT,POST');
        res.header('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept');
        res.send(items);
      }
   );
};

飛行前チェック用

exports.preflight = function (req, res) {
Items.allItems(function (err, items) {
        res.header('Access-Control-Allow-Origin', "*");     // TODO - Make this more secure!!
        res.header('Access-Control-Allow-Methods', 'GET,PUT,POST');
        res.header('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept');
        res.send(200);
    }
  );
};

必要に応じて、res.header()コードを単一の関数に統合できます。

また、上記のように、res.header( 'Access-Control-Allow-Origin'、 "*")の使用に注意してください。これは、誰でもサイトにアクセスできることを意味します。

0
mstreffo

このアプローチにより、複数のドメインを許可する問題が解決しました

app.use(function(req, res, next) {
      var allowedOrigins = ['http://127.0.0.1:8020', 'http://localhost:8020', 'http://127.0.0.1:9000', 'http://localhost:9000'];
      var Origin = req.headers.Origin;
      if(allowedOrigins.indexOf(Origin) > -1){
           res.setHeader('Access-Control-Allow-Origin', Origin);
      }
      //res.header('Access-Control-Allow-Origin', 'http://127.0.0.1:8020');
      res.header('Access-Control-Allow-Methods', 'GET, OPTIONS');
      res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
      res.header('Access-Control-Allow-Credentials', true);
      return next();
    });
0
Ranjoy Ghosh