Sprawdź, czy obowiązuje ta sama polityka pochodzenia

Czy istnieje "bezpieczny" sposób sprawdzenia, czy ta sama polityka pochodzenia ma zastosowanie do adresu URL, zanim spróbuje użyć metod ajax? Oto co mam:

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

Ten rodzaj działa, ale jest to rodzaj ręcznego zgadywania opartego na artykule Wikipedii . Czy istnieje lepszy sposób wstępnego sprawdzania uprawnień między domenami? jQuery jest w porządku używać.

Author: David, 2012-02-23

5 answers

Ciekawe pytanie! Szukałem i nie mogłem znaleźć niczego innego niż to, co napisałeś, ale natknąłem się na to, gdy bawiłem się kodem testowym. Jeśli chcesz po prostu prosty sposób na przetestowanie adresu URL bez składania wniosku, zrobiłbym to tak, jak robisz to. Jeśli nie zależy ci na zrobieniu prośby o przetestowanie, możesz spróbować tego:

Make a simple ajax request to whatever URL you want:

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

Który zwraca obiekt jqXHR, który można następnie sprawdzić:

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

Teraz jedynym problemem jest to, że isRejected() będzie oceniać do true dla każdego pojedynczego przypadku, w którym strona nie ładuje się (tj. 404 Nie znaleziono, itp.), ale możesz sprawdzić kod statusu za pomocą:

ajaxRequest.status;

Wygląda na to, że powyższa linia zwróci 0, gdy spróbujesz złamać tę samą politykę pochodzenia, ale zwróci odpowiedni kod błędu (ponownie, np.

Więc na zakończenie, może mógłbyś spróbować zrobić coś w stylu:

function testSameOrigin(testUrl) {

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

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

Nie a definitywna odpowiedź w jakikolwiek sposób, ale mam nadzieję, że pomoże Ci dowiedzieć się, czego szukasz!

 8
Author: Steve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-29 22:28:35

Czy istnieje "bezpieczny" sposób sprawdzenia, czy ta sama polityka pochodzenia ma zastosowanie do adresu URL, zanim spróbuje użyć metod ajax? Oto co mam:

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;
}
Jest to Bezpieczny i niezawodny sposób, pod warunkiem, że robisz (a raczej nie robisz) pewne rzeczy.

Ten rodzaj działa, ale jest to rodzaj ręcznego zgadywania opartego na artykule w Wikipedii.

Powinno to w pełni działać w "normalnych" okolicznościach. Będzie musiał zostać zmodyfikowany, jeśli planujesz używać skryptów cross-domain scripting.

Jeśli zmodyfikujesz document.domain w swoich skryptach, na przykład z "foo.example.com" i "bar.example.com" do "example.com" twoja testSameOrigin funkcja zwróci false dla " http://example.com ", gdzie w rzeczywistości powinien zwrócić true.

Jeśli planujesz modyfikację document.domain, możesz po prostu dodać czek do swojego skryptu.

Jeśli planujesz używać CORS (patrz link powyżej), aby zezwolić na cross-domeny komunikacja, zwróci również fałszywy wynik negatywny. Ale jeśli używasz CORS, będziesz miał listę domen, z którymi możesz się komunikować i możesz dodać tę listę do tej funkcji.

Czy istnieje lepszy sposób wstępnego sprawdzania limitu domen? jQuery jest w porządku używać.

Prawdopodobnie nie, chociaż warto wspomnieć, że to, co widzisz w konsoli z odpowiedzi Steve ' a, może być "dylematem obserwatora" ... Te błędy wyglądają jakby były wynikający z próby sprawdzenia przez konsolę drugiego okna, niekoniecznie ze skryptu.

Zakładając, że nie zadzierasz z document.domain lub nie korzystasz z CORS, twoje oryginalne rozwiązanie jest prawdopodobnie lepsze, ponieważ nie wymaga dodatkowego żądania, aby określić, czy serwer jest dostępny, czy nie. Nawet jeśli robisz Skrypty między domenami, modyfikowanie funkcji, którą masz teraz, aby ją dostosować, jest prawdopodobnie najlepszym rozwiązaniem.

 12
Author: Dagg Nabbit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:53:51

Wypróbuj również to rozwiązanie.

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"));
    }
  }
});
 2
Author: jo_asakura,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-26 16:22:47

Innym sposobem wykonania skryptu cross domain jest użycie JSON-P. Możesz również przeczytać ten Artykuł . W przeciwnym razie Skrypty cross domain nie są dozwolone przez tę samą politykę pochodzenia.

 0
Author: Alberto De Caro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-28 23:50:02

Na podstawie odpowiedzi Dagga Nabbita wydaje się to nieco bardziej kompletne:

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

Zastrzeżenia, które mogę wymyślić:

 0
Author: B T,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-17 10:45:55