Überprüfen Sie, ob die Richtlinie zur gleichen Herkunft gilt

Lesezeit: 7 Minuten

Benutzer-Avatar
David Helling

Gibt es eine “sichere” Möglichkeit zu überprüfen, ob dieselbe Ursprungsrichtlinie für eine URL gilt, bevor Sie tatsächlich versuchen, Ajax-Methoden zu verwenden? Hier ist, was ich habe:

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;
}

Diese Art von Arbeit, aber es ist eine Art manuelle Vermutung basierend auf Wikipedia-Artikel. Gibt es eine bessere Möglichkeit, die domänenübergreifende Genehmigung vorab zu überprüfen? jQuery ist OK zu verwenden.

  • Wenn Sie eine domänenübergreifende Anfrage stellen, schlägt dies fehl readystate=4 und statuscode=0, was einer abgebrochenen Anfrage ähnelt. Da Sie sich sowieso vor abgebrochenen Anfragen schützen müssen, wozu brauchen Sie diese Prüfung? Ich habe das Gefühl, dass diese Sicherheitsmaßnahme von außen durchgesetzt wird, Sie haben keine Kontrolle darüber, daher ist jede Überprüfung aus der Umgebung per Definition falsch. Ich denke also nicht, dass Sie jemals danach suchen sollten, lassen Sie die Anfrage einfach fehlschlagen.

    – Halkyon

    3. März 2012 um 20:38 Uhr


Benutzer-Avatar
Dagg Nabbit

Gibt es eine “sichere” Möglichkeit zu überprüfen, ob dieselbe Ursprungsrichtlinie für eine URL gilt, bevor Sie tatsächlich versuchen, Ajax-Methoden zu verwenden? Hier ist, was ich habe:

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;
}

Dies ist eine sichere und zuverlässige Methode, vorausgesetzt, Sie tun (oder besser gesagt nicht) bestimmte Dinge.

Diese Art funktioniert, aber es ist eine Art manuelle Vermutung basierend auf dem Wikipedia-Artikel.

Dies sollte unter den “normalen” Umständen vollständig funktionieren. Es muss geändert werden, wenn Sie domänenübergreifendes Skripting verwenden möchten.

Wenn Sie ändern document.domain in Ihren Skripten, zum Beispiel von “foo.example.com” und “bar.example.com” zu “example.com”. testSameOrigin Funktion würde zurückkehren false zum “http://beispiel.com“, wo es eigentlich zurückkehren sollte true.

Wenn Sie eine Änderung planen document.domainkönnen Sie einfach ein Häkchen dafür in Ihrem Skript hinzufügen.

Wenn Sie vorhaben, CORS (siehe obigen Link) zu verwenden, um eine domänenübergreifende Kommunikation zu ermöglichen, wird auch ein falsch negatives Ergebnis zurückgegeben. Aber wenn Sie CORS verwenden, haben Sie eine Liste von Domänen, mit denen Sie kommunizieren können, und Sie können diese Liste auch zu dieser Funktion hinzufügen.

Gibt es eine bessere Möglichkeit, die domänenübergreifende Genehmigung vorab zu überprüfen? jQuery ist OK zu verwenden.

Wahrscheinlich nicht, obwohl es erwähnenswert sein könnte, dass das, was Sie in der Konsole von Steves Antwort sehen, das “Beobachterdilemma” sein könnte … Diese Fehler scheinen darauf zurückzuführen zu sein, dass die Konsole versucht, das andere Fenster zu inspizieren, nicht unbedingt von das Skript.

Vorausgesetzt, du spielst nicht mit document.domain oder CORS verwenden, ist Ihre ursprüngliche Lösung wahrscheinlich besser, da keine zusätzliche Anfrage gestellt werden muss, um festzustellen, ob der Server verfügbar ist oder nicht. Selbst wenn Sie domänenübergreifendes Skripting durchführen, ist es wahrscheinlich am besten, die Funktion, die Sie jetzt haben, zu ändern, um sie aufzunehmen.

  • Während dies eine gute Möglichkeit ist, nach CORS-Anforderungen zu suchen, bricht es in IE7 ab, während der generierte Anker keine Informationen über den Link zurückgibt, also zum Beispiel einen Link auswertet, wie z <a href='main.html'></a> in IE7 wird es zurückkehren a.href => "main.html" a.hostname => "" usw. Ich versuche immer noch herauszufinden, wie ich damit in IE7 umgehen soll. konnte aber keine gute Lösung finden. da es niemals die vollständige href erstellen wird.

    – Zanona

    29. August 2012 um 15:07 Uhr


  • Welche document.domain-Prüfung würden Sie hinzufügen? Würde einfach tauschen loc.hostname mit document.domain richtig sein?

    – BT

    7. Juli 2014 um 20:03 Uhr

  • @BT a.hostname wäre immer noch “foo.example.com” und document.domain wäre einfach “example.com”. Es müsste eine Sonderfallprüfung sein, dh wenn Sie wissen, dass Sie beide umschreiben document.domains zu “example.com”, würde die Prüfung des Hostnamens in etwa so aussehen a.hostname == loc.hostname || a.hostname == "foo.example.com"

    – Dagg Nabbit

    7. Juli 2014 um 21:04 Uhr

  • Ich bin auf einen Fall gestoßen, wo a.port != loc.port weil der erste als 80 und der zweite als leer erscheint.

    – merk

    31. März 2015 um 15:16 Uhr


Interessante Frage! Ich habe mich umgesehen und konnte nichts anderes als das finden, was Sie gepostet haben, aber ich bin darauf gestoßen, als ich mit Testcode herumgespielt habe. Wenn Sie nur eine einfache Möglichkeit suchen, eine URL zu testen, ohne eine Anfrage zu stellen, würde ich es so machen, wie Sie es tun. Wenn Sie keine Testanfrage stellen möchten, können Sie Folgendes versuchen:

Machen Sie eine einfache Ajax-Anfrage an die gewünschte URL:

var ajaxRequest = $.ajax({
  url: 'http://www.google.com',
  async: false
});

was ein zurückgibt jqXHR Objekt, das Sie dann überprüfen können:

ajaxRequest.isRejected(); // or...
ajaxRequest.isResolved();

Nun, das einzige Problem dabei ist das isRejected() wird zu bewerten true für jeden einzelnen Fall, in dem die Seite nicht geladen wird (z. B. 404 Not Found usw.), aber Sie können den Statuscode überprüfen mit:

ajaxRequest.status;

Es sieht so aus, als würde die obige Zeile zurückkehren 0 wenn Sie versuchen, dieselbe Ursprungsrichtlinie zu brechen, aber in anderen Fällen wird der entsprechende Fehlercode (wiederum, dh 404) zurückgegeben.

Zum Abschluss könnten Sie vielleicht versuchen, Folgendes zu tun:

function testSameOrigin(testUrl) {

  var ajaxRequest = $.ajax({
    url: testUrl,
    async: false
  });

  return ajaxRequest.isRejected() && ajaxRequest.status === 0;
}

Keine definitive Antwort, aber ich hoffe, es hilft Ihnen herauszufinden, wonach Sie suchen!

  • Ja, das ist ein interessanter Ansatz. In meinem ursprünglichen Fall wollte ich die unangenehmen Konsolenfehler beseitigen, die Sie erhalten, wenn Sie den abgelehnten Ajax-Aufruf ausführen, indem Sie versuchen, die URL zu “validieren”. Ich habe auch erst kürzlich festgestellt, dass das Ausführen einer Ajax-Anfrage für eine lokale Datei (die Datei: Protokoll) auch jedes Mal fehlschlägt. Das ist also ein weiterer Fall, den es zu überprüfen gilt …

    – David Hellsing

    29. Februar 2012 um 23:37 Uhr

  • Sie können Ajax für lokale Dateien verwenden, indem Sie die isLocal Flagge zu true api.jquery.com/jQuery.ajax/#jQuery-ajax-settings

    – Steve

    1. März 2012 um 3:11 Uhr

Versuchen Sie auch diese Lösung.

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 + "https://stackoverflow.com/") ||
    (url === srOrigin || url.slice(0, srOrigin.length + 1) === srOrigin + "https://stackoverflow.com/") ||
    // 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"));
    }
  }
});

Eine andere Möglichkeit, domänenübergreifendes Skript auszuführen, ist die Verwendung von JSON-P. Sie können dies auch lesen Artikel. Andernfalls wird das domänenübergreifende Scripting von der Richtlinie für denselben Ursprung nicht zugelassen.

Benutzer-Avatar
BT

Aufbauend auf Dagg Nabbits Antwort scheint dies etwas vollständiger zu sein:

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

Vorbehalte, die mir einfallen:

1094730cookie-checkÜberprüfen Sie, ob die Richtlinie zur gleichen Herkunft gilt

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy