检查是否适用同源策略



在实际尝试使用 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是可以使用的。

在实际尝试使用 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",您的testSameOrigin函数将返回"http://example.com"的false,实际上它应该返回true

如果您打算修改document.domain,则可以在脚本中添加简单的检查。

如果您计划使用 CORS(请参阅上面的链接(来允许跨域通信,它还将返回漏报。但是,如果您使用的是 CORS,您将拥有一个可以与之通信的域列表,您也可以将该列表添加到此函数中。

有没有更好的方法来预先检查跨域限额?jQuery可以使用。

可能不是,尽管值得一提的是,您在控制台中看到的史蒂夫的答案可能是"观察者的困境"......这些错误看起来像是控制台尝试检查另一个窗口的结果,不一定是脚本造成的。

假设您没有弄乱document.domain或使用 CORS,您的原始解决方案可能会更好,因为它不需要发出额外的请求来确定服务器是否可用。即使您正在执行一些跨域脚本,修改您现在拥有的功能以适应它也可能是您最好的选择。

有趣的问题! 我四处搜索,除了您发布的内容之外找不到任何其他内容,但是当我弄乱一些测试代码时,我确实遇到了这个问题。 如果您只是想要一种简单的方法来测试URL,而无需发出请求,我会按照您的方式进行操作。 如果您不关心提出测试请求,可以尝试以下操作:

向您想要的任何 URL 发出简单的 ajax 请求:

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

返回一个 jqXHR 对象,然后您可以检查该对象:

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

现在,唯一的问题是isRejected()将评估为页面未加载的每个情况(即 404 未找到等(true,但您可以使用以下方法检查状态代码:

ajaxRequest.status;

当您尝试破坏同源策略时,看起来上面的行将返回0,但在其他情况下它将返回适当的错误代码(再次,即 404(。

所以总结一下,也许你可以尝试做这样的事情:

function testSameOrigin(testUrl) {
  var ajaxRequest = $.ajax({
    url: testUrl,
    async: false
  });
  return ajaxRequest.isRejected() && ajaxRequest.status === 0;
}

无论如何都不是一个明确的答案,但我希望它能帮助你弄清楚你在寻找什么!

也试试这个解决方案。

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

执行跨域脚本的另一种方法是使用 JSON-P。您也可以阅读本文。否则,同源策略不允许跨域脚本。

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

我能想到的注意事项:

  • 不考虑文档域
  • 不考虑 CORS
  • 在IE7中不起作用(如zanona所述(
  • 在奇怪的环境(如 android(中不起作用,您可以在其中访问任意file://协议路径(有人请验证这一点,有关 android 的信息可能已过时 https://security.stackexchange.com/questions/25138/same-origin-policy-for-file-urls-in-android-browser(

相关内容

  • 没有找到相关文章

最新更新