私は、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);
});
しかし、それでも同じエラーが返されます。ただし、これが機能したとしても、理想的なソリューションとは思えません。世界中のユーザーがリクエストを送信できるようにしたいからです。
誰もがNodeアプリにアクセスできるようにしたい場合は、
res.header('Access-Control-Allow-Origin', "*")
これにより、任意のオリジンからのリクエストが許可されます。 CORS enable サイトには、さまざまなAccess-Control-Allowヘッダーとその使用方法に関する多くの情報があります。
Chromeを使用している場合は、 this localhostおよびAccess-Control-Allow-Originに関するバグバグをご覧ください。別の StackOverflowの質問 があり、問題の詳細を説明しています。
ローカルホストでは、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でホストリクエストヘッダーとサーバーホストを取得する方法を理解できると思います。)
私が推測しているローカルホストへのフェッチ呼び出しをバックボーンコードと同じディレクトリの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');
});
正しいヘッダーを設定する必要がある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'、 "*")の使用に注意してください。これは、誰でもサイトにアクセスできることを意味します。
このアプローチにより、複数のドメインを許可する問題が解決しました
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();
});