我正在使用 jquery-fileupload 来允许用户将文件上传到外部服务(更具体地说是 Cloudinary):
<input type='file' name='file' class='cloudinary-fileupload'
data-url='https://api.cloudinary.com/v1_1/wya/auto/upload' />
<script>
$('.cloudinary-fileupload').fileupload();
</script>
由于是外部目标,浏览器会发起 CORS 请求。但是,我注意到浏览器预先设置了 CORS 预检请求。 http://www.html5rocks.com/en/tutorials/cors/提供了关于何时触发预检请求以及何时不触发的很好的见解。据我所知,我的请求满足作为 CORS 简单请求的所有标准(请参阅“CORS 请求类型”部分)。
发送到外部服务的文件上传请求:
POST /v1_1/wya/image/upload HTTP/1.1
Host: api.cloudinary.com
Connection: keep-alive
Content-Length: 22214
Accept: */*
Origin: http://wya.herokuapp.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarym73rCIa6t8eTNkTa
Referer: http://wya.herokuapp.com/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: sv-SE,sv;q=0.8,en-US;q=0.6,en;q=0.4,de;q=0.2
在文件上传请求之前发送到外部服务的附加预检请求:
OPTIONS /v1_1/wya/image/upload HTTP/1.1
Host: api.cloudinary.com
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://wya.herokuapp.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36
Access-Control-Request-Headers: accept, content-type
Accept: */*
Referer: http://wya.herokuapp.com/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: sv-SE,sv;q=0.8,en-US;q=0.6,en;q=0.4,de;q=0.2
有没有办法避免这个额外的预检请求?据我所知,文件上传请求是一个 CORS 简单请求,因为它是一个 HTTP POST,带有 Content-Type multipart/form-data 并且只有简单的请求 HTTP 标头。
我想摆脱额外的预检请求的原因是 Cloudinary 发送 HTTP 302/304 重定向作为对文件上传的响应。浏览器不遵循这些重定向。Chrome 失败并显示以下消息:
XMLHttpRequest cannot load https://api.cloudinary.com/v1_1/wya/image/upload.
The request was redirected to 'http://wya.herokuapp.com/upload?bytes=21534&created_at=2014-02-12T09%3A04%3…d5b62ebb92b9236e5be6d472df242d016&type=upload&version=1392195882&width=723',
which is disallowed for cross-origin requests that require preflight.