Подтвердить что ты не робот

Проверьте, применяется ли та же политика происхождения

Существует ли "безопасный" способ проверить, применяется ли одна и та же политика происхождения к URL-адресу, прежде чем пытаться использовать методы ajax? Вот что я имею:

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 подходит для использования.

4b9b3361

Ответ 1

Интересный вопрос! Я искал вокруг и не мог найти ничего, кроме того, что вы разместили, но мне это показалось, когда я возился с некоторым тестовым кодом. Если вы просто хотите простой способ проверить URL-адрес без запроса, я бы сделал это так, как вы это делаете. Если вы не хотите делать запрос на тестирование, вы можете попробовать следующее:

Сделайте простой запрос ajax по любому URL-адресу, который вы хотите:

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

который возвращает объект jqXHR, который вы можете проверить:

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

Теперь единственная проблема заключается в том, что isRejected() будет оценивать значение true для каждого отдельного случая, когда страница не загружается (т.е. 404 Not Found и т.д.), но вы можете проверить код состояния с помощью

ajaxRequest.status;

Похоже, что вышеприведенная строка вернет 0 при попытке разбить одну и ту же политику происхождения, но в других случаях вернет соответствующий код ошибки (опять же, например, 404).

Итак, чтобы закончить, возможно, вы могли бы попробовать сделать что-то вроде:

function testSameOrigin(testUrl) {

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

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

Не окончательный ответ любым способом, но я надеюсь, что это поможет вам понять, что вы ищете!

Ответ 2

Существует ли "безопасный" способ проверить, применяется ли одна и та же политика происхождения к URL-адресу, прежде чем пытаться использовать методы ajax? Вот что я имею:

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 для " http://example.com", где на самом деле он должен возвращать true.

Если вы планируете модифицировать document.domain, вы можете добавить просто добавьте проверку для своего script.

Если вы планируете использовать CORS (см. ссылку выше), чтобы разрешить междоменную связь, она также вернет ложный отрицательный результат. Но если вы используете CORS, у вас будет список доменов, с которыми вы можете общаться, и вы также можете добавить этот список к этой функции.

Есть ли лучший способ предварительной проверки надбавки за кросс-домен? jQuery подходит для использования.

Вероятно, нет, хотя, возможно, стоит упомянуть, что то, что вы видите на консоли от ответа Стива, может быть "дилеммой наблюдателя"... Эти ошибки выглядят так, как будто они возникают из-за того, что консоль пытается проверить другое окно, не обязательно из script.

Предполагая, что вы не возитесь с document.domain или используете CORS, ваше исходное решение, вероятно, лучше, так как не нужно делать дополнительный запрос, чтобы определить, доступен ли сервер или нет. Даже если вы выполняете некоторые междоменные скрипты, изменение функции, которую вы теперь можете разместить, вероятно, будет вашим лучшим выбором.

Ответ 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"));
    }
  }
});

Ответ 4

Другим способом выполнения кросс-домена script является использование JSON-P. Вы также можете прочитать статью . В противном случае междоменная сценария не допускается одной политикой происхождения.

Ответ 5

Создание ответа 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:'
}

Оговорки, о которых я могу думать:

  • не учитывает document.domain
  • не учитывает CORS
  • Не работает в IE7 (как упоминалось zanona)
  • Не работает в странных средах (например, android), где вы можете получить доступ к произвольным маршрутам протокола file:// (кто-то, пожалуйста, подтвердите это, информация об андроиде может устаревать https://security.stackexchange.com/info/25138/same-origin-policy-for-file-urls-in-android-browser)