実際にajaxメソッドを使用する前に、同じOriginポリシーがURLに適用されるかどうかを確認する「安全な」方法はありますか?これが私が持っているものです:
function testSameOrigin(url) {
var loc = window.location,
a = document.createElement('a');
a.href = url;
return a.hostname == loc.hostname &&
a.port == loc.port &&
a.protocol == loc.protocol;
}
この種の作業は機能しますが、 ウィキペディアの記事 に基づいた手動の推測のようなものです。クロスドメイン許容量を事前にチェックするより良い方法はありますか? jQueryは使用しても問題ありません。
興味深い質問です!調べてみたところ、投稿したもの以外は見つかりませんでしたが、テストコードをいじっていたときに出くわしました。リクエストを行わずにURLをテストする簡単な方法が必要な場合は、私が行っている方法で行います。テストのリクエストを気にしない場合は、次のことを試してみてください。
必要なURLに簡単なajaxリクエストを作成します。
_var ajaxRequest = $.ajax({
url: 'http://www.google.com',
async: false
});
_
これはjqXHR
オブジェクトを返し、それを確認できます。
_ajaxRequest.isRejected(); // or...
ajaxRequest.isResolved();
_
さて、これに関する唯一の問題は、ページがロードされない(つまり、404 Not Foundなど)すべてのケースでisRejected()
がtrue
と評価されることですが、確認することができますステータスコード:
_ajaxRequest.status;
_
同一生成元ポリシーを破ろうとすると、上記の行は_0
_を返すように見えますが、それ以外の場合は適切なエラーコード(つまり404)を返します。
まとめると、次のようなことを試してみることができます。
_function testSameOrigin(testUrl) {
var ajaxRequest = $.ajax({
url: testUrl,
async: false
});
return ajaxRequest.isRejected() && ajaxRequest.status === 0;
}
_
決して決定的な答えではありませんが、それがあなたが探しているものを理解するのに役立つことを願っています!
実際にajaxメソッドを使用する前に、同じOriginポリシーがURLに適用されるかどうかを確認する「安全な」方法はありますか?これが私が持っているものです:
function testSameOrigin(url) {
var loc = window.location,
a = document.createElement('a');
a.href = url;
return a.hostname == loc.hostname &&
a.port == loc.port &&
a.protocol == loc.protocol;
}
これは、特定のことを実行している(または実行していない)場合に限り、安全で信頼性の高い方法です。
この種の作業は機能しますが、ウィキペディアの記事に基づいた手動の推測のようなものです。
これは、「通常の」状況で完全に機能するはずです。 クロスドメインスクリプティング を使用する場合は、変更する必要があります。
スクリプトでdocument.domain
を変更すると、たとえば「foo.example.com」や「bar.example.com」から「example.com」に変更すると、testSameOrigin
関数はfalse
for " http://example.com "、実際にはtrue
を返す必要があります。
document.domain
の変更を計画している場合は、スクリプトにそのチェックを追加するだけで追加できます。
CORS(上記のリンクを参照)を使用してクロスドメイン通信を許可することを計画している場合は、フォールスネガティブも返します。ただし、CORSを使用している場合は、通信できるドメインのリストがあり、そのリストをこの関数に追加することもできます。
クロスドメイン許容量を事前にチェックするより良い方法はありますか? jQueryは使用しても問題ありません。
おそらくそうではありませんが、スティーブの答えからコンソールに表示されているのは「オブザーバーのジレンマ」である可能性があることを言及する価値があるかもしれません...これらのエラーは、コンソールが他のウィンドウを検査しようとしたためであるように見えますが、必ずしもスクリプト。
document.domain
をいじったり、CORSを使用したりしていないと仮定すると、サーバーが使用可能かどうかを判断するために追加のリクエストを行う必要がないため、元のソリューションの方がおそらく優れています。クロスドメインスクリプティングを行っている場合でも、それに対応するために現在持っている関数を変更するのがおそらく最善の策です。
このソリューションも試してください。
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function sameOrigin(url) {
// test that a given url is a same-Origin URL
// url could be relative or scheme relative or absolute
var Host = window.document.location.Host; // Host + port
var protocol = window.document.location.protocol;
var srOrigin = '//' + Host;
var Origin = protocol + srOrigin;
// Allow absolute or scheme relative URLs to same Origin
return (url === Origin || url.slice(0, Origin.length + 1) === Origin + '/') ||
(url === srOrigin || url.slice(0, srOrigin.length + 1) === srOrigin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}
// if you want to check before you make a call
if (!csrfSafeMethod(data.type) && sameOrigin(data.url)) {
// ...
}
// or if you want to set csrf token
$.ajax({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
}
}
});
Dagg Nabbitの答えに基づいて、これはもう少し完全に思えます。
function sameOrigin(url) {
var loc = window.location, a = document.createElement('a')
a.href = url
return a.hostname === loc.hostname &&
a.port === loc.port &&
a.protocol === loc.protocol &&
loc.protocol !== 'file:'
}
私が考えることができる警告:
file://
プロトコルパスにアクセスできる奇妙な環境(Androidなど)では機能しません(誰かがこれを確認してください、Android古い可能性があります https://security.stackexchange.com/questions/25138/same-Origin-policy-for-file-urls-in-Android-browser )