了解基于 CORS 的 XMLHttpRequest (responseText)

Posted

技术标签:

【中文标题】了解基于 CORS 的 XMLHttpRequest (responseText)【英文标题】:Understanding XMLHttpRequest over CORS (responseText) 【发布时间】:2012-11-04 05:37:17 【问题描述】:

对于一个项目,我正在研究各种 html5 和 javascript 元素以及它们周围的安全性,我现在正试图了解 CORS。

根据我的测试,如果我删除..

<?php
 header("Access-Control-Allow-Origin: *"); 
 header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
 ?>

..从尝试访问的页面中,我在 Chrome 的控制台日志中看到以下内容:

XMLHttpRequest cannot load http://www.bla.com/index.php. Origin http://bla2.com is not allowed by Access-Control-Allow-Origin.

我理解这是正确的,但是 Wireshark 在返回中显示 HTTP/1.1 200 OK,并且在数据中显示了所请求页面的来源。那么,是不是只有浏览器和 Javascript 才阻止 responseText 以任何实质性方式被使用,即使它实际上已经被传输了?

代码如下:

  function makeXMLRequest() 
  xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange = function() 
    if (xmlhttp.readyState==4) 
        alert(xmlhttp.responseText);
    

xmlhttp.open("GET","http://www.bla.com/index.php",true);
xmlhttp.send();

提前致谢。

【问题讨论】:

【参考方案1】:

那么,是不是只有浏览器和 Javascript 才阻止 responseText 以任何实质性方式被使用,即使它实际上已被传输?

是的。您可以使用 JS 提出任何您喜欢的请求。

同源策略禁止访问数据。

执行恶意操作的请求(例如“POST http://bank.example/give/money?to=attacker”或“POST http://forum.example.com/post?message=spamspamspamspam"”称为CSRF attacks,必须由服务器进行防御。

【讨论】:

那么我应该把Access-Control-Allow-Origin放在哪里? @GtiClicker :它在问题中的位置(在它被删除之前)很好 但我使用的是 fetch 而不是 XMLHttpRequest @GtiClicker — 那又怎样?问题中的代码没有将Access-Control-Allow-Origin 放在涉及 XMLHttpRequest 的代码中。 (如果您有新问题,请发送电子邮件至new question。不要只评论相关的答案)。【参考方案2】:

对于像 GET 或 POST 这样的“简单”HTTP 动词,是的,整个页面被获取,然后浏览器决定 JavaScript 是否使用这些内容。服务器不需要知道请求来自哪里; 浏览器的工作是检查来自服务器的回复并确定是否允许 JS 看到内容。

对于像 PUT 或 DELETE 这样的“非简单”HTTP 动词,浏览器使用 OPTIONS 请求发出“预检请求”。在这种情况下,浏览器首先检查是否支持域动词,分别检查Access-Control-Allow-OriginAccess-Control-Allow-Methods。 (有关更多信息,请参阅 HTML5 Rocks 的 CORS page 上的“处理不太简单的请求”。)预检响应还列出了允许的非简单标头,包含在 Access-Control-Allow-Headers 中。

这是因为允许客户端向服务器发送 DELETE 请求可能是非常糟糕的,即使 JavaScript 永远无法看到跨域结果 - 再次记住,服务器通常没有任何义务进行验证请求来自合法域(尽管它可能使用请求中的 Origin 标头这样做)。

【讨论】:

设置 XMLHttpRequest.withCredentials 时会发生什么?如果响应不包含 Access-Control-Allow-Credentials,则不会发送凭据。即使对简单的 GET 请求,这也需要进行预检,但我在服务器日志中看不到任何内容。

以上是关于了解基于 CORS 的 XMLHttpRequest (responseText)的主要内容,如果未能解决你的问题,请参考以下文章

Ajax中XMLHttpReques

Ajax

了解 CORS

了解 AJAX CORS 和安全注意事项

了解 AJAX CORS 和安全注意事项

基于CORS的GeoServer跨域访问策略