25

実際にajaxメソッドを使用する前に、同じオリジンポリシーが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は使用しても問題ありません。

4

5 に答える 5

16

実際にajaxメソッドを使用する前に、同じオリジンポリシーが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」に変更すると、関数testSameOriginfalsehttp://example.com」に戻りますが、実際にはを返す必要がありtrueます。

変更を計画している場合はdocument.domain、スクリプトにそのチェックを追加するだけです。

CORS(上記のリンクを参照)を使用してクロスドメイン通信を許可することを計画している場合は、フォールスネガティブも返されます。ただし、CORSを使用している場合は、通信できるドメインのリストがあり、そのリストをこの関数に追加することもできます。

クロスドメイン許容量を事前にチェックするより良い方法はありますか?jQueryは使用しても問題ありません。

おそらくそうではありませんが、スティーブの答えからコンソールに表示されているのは「オブザーバーのジレンマ」である可能性があります...これらのエラーは、コンソールが他のウィンドウを検査しようとしたために発生したように見えますが、必ずしもスクリプト。

CORSをいじっdocument.domainたり使用したりしていないと仮定すると、サーバーが使用可能かどうかを判断するために追加のリクエストを行う必要がないため、元のソリューションの方がおそらく優れています。クロスドメインスクリプティングを行っている場合でも、それに対応するために現在持っている関数を変更するのがおそらく最善の策です。

于 2012-03-05T16:02:12.250 に答える
8

面白い質問です!調べてみたところ、投稿したもの以外は見つかりませんでしたが、テストコードをいじっていたときに出くわしました。リクエストを行わずに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;
}

決して決定的な答えではありませんが、それがあなたが探しているものを理解するのに役立つことを願っています!

于 2012-02-29T22:28:35.397 に答える
3

このソリューションも試してください。

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"));
    }
  }
});
于 2015-01-26T16:22:47.027 に答える
0

クロスドメインスクリプトを実行する別の方法は、JSON-Pを使用することです。この記事も読むことができます。それ以外の場合、クロスドメインスクリプティングは同一生成元ポリシーで許可されません。

于 2012-02-28T23:50:02.783 に答える
0

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:'
}

私が考えることができる警告:

于 2014-07-07T20:31:04.517 に答える