检查是否适用相同的原始政策
在实际尝试使用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可以使用。
有趣的问题! 我四处搜索,除了你发布的内容之外找不到任何其他内容,但是当我搞乱一些测试代码时,我确实遇到了这个问题。 如果您只想要一种简单的方法来测试URL而不提出请求,我会按照您的方式进行操作。 如果您不关心提出测试请求,您可以尝试这样做:
对你想要的任何URL做一个简单的ajax请求:
var ajaxRequest = $.ajax({ url: 'http://www.google.com', async: false });
返回一个jqXHR
对象,然后您可以检查:
ajaxRequest.isRejected(); // or... ajaxRequest.isResolved();
现在,唯一的问题是isRejected()
将为页面未加载的每个案例(即404 Not Found等)评估为true
,但您可以使用以下命令检查状态代码:
ajaxRequest.status;
当您尝试中断相同的原始策略时,上面的行看起来会返回0
,但在其他情况下它将返回相应的错误代码(再次,即404)。
总结一下,也许你可以尝试做类似的事情:
function testSameOrigin(testUrl) { var ajaxRequest = $.ajax({ url: testUrl, async: false }); return ajaxRequest.isRejected() && ajaxRequest.status === 0; }
无论如何不是一个明确的答案,但我希望它可以帮助你弄清楚你在寻找什么!
在实际尝试使用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,则会有一个可以与之通信的域列表,您也可以将该列表添加到此function中。
有没有更好的方法来预先检查跨域允许? jQuery可以使用。
可能不是,虽然值得一提的是,你在史蒂夫的回答中看到你在控制台看到的可能是“观察者的困境”……这些错误看起来像是由于控制台试图检查另一个窗口而不是来自剧本。
假设您没有使用document.domain
或使用CORS,原始解决方案可能更好,因为它不需要额外的请求来确定服务器是否可用。 即使您正在进行一些跨域脚本编写,修改现在可以容纳它的function可能是您最好的选择。
尝试这个解决方案。
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 ie 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:' }
我能想到的警告:
- 不考虑document.domain
- 不考虑CORS
- 在IE7中不起作用(如zanona所述)
- 不能在奇怪的环境(如android)中工作,你可以访问任意
file://
协议路径(有人请validation这一点,有关android的信息可能已过时https://security.stackexchange.com/questions/25138/same -origin-policy-for-file-urls-in-android-browser )