为什么浏览器允许xorigin POST但不允许PUT?

时间:2016-09-03 14:46:52

标签: javascript ajax browser cross-browser

考虑使用XMLHttpRequest的简单示例。

以下帖子正确(您可以在网络标签中看到它或将浏览器指向http://requestb.in/yckncpyc),尽管它会向控制台显示警告

  

XMLHttpRequest无法加载http://requestb.in/yckncpyc。没有   请求中存在“Access-Control-Allow-Origin”标头   资源。因此,不允许原点'null'访问。

const method = "POST"
const req = new XMLHttpRequest()	
req.open(method, 'http://requestb.in/yckncpyc')
req.send("foobar")
console.log("sent")
req.addEventListener('load', function() { console.log(req.status, req.response) })

不确定。我明白了。我没有得到的是为什么仅仅改变用于PUT的动词会导致完全不同的东西。发送的请求是OPTIONS预检请求并打印

  

XMLHttpRequest无法加载http://requestb.in/yckncpyc。回应   预检请求未通过访问控制检查:否   请求中存在“Access-Control-Allow-Origin”标头   资源。因此,不允许原点'null'访问。

const method = "PUT"
const req = new XMLHttpRequest()	
req.open(method, 'http://requestb.in/yckncpyc')
req.send("foobar")
console.log("sent")
req.addEventListener('load', function() { console.log(req.status, req.response) })

为什么浏览器*对待这些不同?这似乎是安全性所做的事情,但实际上没有任何意义,因为攻击者总是可以使用POST而不是PUT。

那么这里的逻辑是什么?

  • 在Chrome 52,Safari 9.1.2
  • 中尝试过此操作

1 个答案:

答案 0 :(得分:1)

BlobGETHEAD请求(以及其他一些限制)可以跨域而无需额外通信。无法检查响应,但允许请求。

其他任何事情都需要预检请求来检查目标网站的标头,以查看是否允许该请求。

这种设置的原因是历史上允许来自浏览器的POSTGETHEAD作为HTML语义的自然部分。脚本和CSS和图像的标签执行GET请求,表单执行POST。因此,当引入CORS内容时,允许这些内容假设站点不再像XHR世界那样容易受到简单请求的影响,那么它们就处于更简单的非XHR世界中。

允许这么简单的请求,浏览器会查看响应标头,以决定是否允许跨源页面中的请求代码查看响应内容。对于其他请求,浏览器首先发送POST请求以检查CORS响应头。只有当它看起来没问题时(也就是说,如果响应头包含适当的“是,那就是OK”标题),XHR将被允许继续。