跨域分块上传使用CORS

我有用户提交的文件,我试图上传10 MB块。 我目前正在使用原始的XMLHttpRequest(和XDomainRequest)在前端推送每个单独的切片( File.prototoype.slice )。 后端是使用上传模块的 Nginx。

仅供参考,以下是我如何使用slice的概要:

 element.files[0].slice(...) 

我了解跨浏览器前缀的方法webkitSlicemozSlice等等。

我遇到的问题是实际进行跨域请求。 我从server.local上传到upload.server.local 。 在Firefox中, options请求正常,然后实际post失败。 在Chrome和Opera中, options请求失败

  OPTIONS https://URL Resource failed to load 

以下是Firefox的标题:

请求头

 OPTIONS /path/to/asset HTTP/1.1 Host: upload.server.local:8443 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Origin: https://server.local:8443 Access-Control-Request-Method: POST Access-Control-Request-Headers: content-disposition,content-type,x-content-range,x-session-id Connection: keep-alive Pragma: no-cache Cache-Control: no-cache 

响应头

 HTTP/1.1 204 No Content Server: nginx/1.2.6 Date: Wed, 13 Feb 2013 03:27:44 GMT Connection: keep-alive access-control-allow-origin: https://server.local:8443 Access-Control-Allow-Methods: POST, OPTIONS Access-Control-Allow-Headers: x-content-range, origin, content-disposition, x-session-id, content-type, cache-control, pragma, referrer, host access-control-allow-credentials: true Access-Control-Max-Age: 10000 

实际的post请求永远不会离开浏览器。 Nginx的访问日志永远不会看到post 。 浏览器由于某种原因暂停。 我如何解开为什么这个post被阻止?

 Chromium 24 Firefox 18 Opera 12.14 

我已经validation所有浏览器在这里正确支持CORS。

通过指向我的上传到https://cors-test.appspot.com/test ,我已经确认问题是肯定与服务器端的标题。

如果预检检查没有返回足够的权限,则POST不会离开浏览器,因此POST请求没有完全授权。 问题中包含的请求/响应确实对我来说足够了。

  • 你确定你在XMLHttpRequest中设置了withCredentials = true吗?
  • 您确定您的服务器上有有效的(不是自签名的)SSL证书吗? 即使添加了用于浏览带有无效证书的网站的例外情况,HTTPS也可能会通过CORS检查。
  • 你有没有尝试清空你的缓存? 您的响应头中设置了Access-Control-Max-Age: 10000 。 接近3个小时。 我知道你在这方面的工作比这个要长,但是在测试的时候,尤其是把这个头部设置为零,所以你不会因浏览器缓存旧的访问权限而发疯。

一般来说,我会首先尽可能地放宽CORS头文件,慢慢地调整安全性以查看失败的位置。 但是,这不是完全简单的。 例如,根据CORS的MDN文档 ,

在响应有证书请求时,服务器必须指定一个域,并且不能使用通配。 上面的例子将失败,如果头被通配为: Access-Control-Allow-Origin: *

当我把你的问题的请求部分发送到https://cors-test.appspot.com/test ,我回头看看以下内容:

 HTTP/1.1 200 OK Cache-Control: no-cache Access-Control-Allow-Origin: https://server.local:8443 Access-Control-Allow-Headers: content-disposition,content-type,x-content-range,x-session-id Access-Control-Allow-Methods: POST Access-Control-Max-Age: 0 Access-Control-Allow-Credentials: true Cache-Control: no-cache Expires: Fri, 01 Jan 1990 00:00:00 GMT Content-Type: application/json Content-Encoding: gzip Content-Length: 35 Vary: Accept-Encoding Date: Thu, 23 May 2013 06:37:34 GMT server: Google Frontend 

所以你可以从那里开始,并添加更多的安全性,直到它打破了什么是罪魁祸首。