Let's consider a straightforward example of utilizing the XMLHttpRequest
.
The following code snippet functions correctly (you can verify in the network tab or by navigating your browser to http://requestb.in/yckncpyc
) despite displaying a warning in the console:
XMLHttpRequest cannot load . No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
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) })
I understand that part. What I find confusing is that switching the HTTP verb to PUT
leads to a completely different outcome. The request made turns into an OPTIONS
preflight request and returns:
XMLHttpRequest cannot load . Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
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) })
Why does the behavior vary for these two scenarios? It appears to be a security measure, but one that may seem illogical since an attacker could easily use a POST instead of a PUT.
What is the rationale behind this differentiation?
- I've tested this in Chrome 52 and Safari 9.1.2