nginx - 使用 CORS 的跨域分块上传

标签 nginx xmlhttprequest cross-domain cors fileapi

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

仅供引用,这里是我如何使用的概要 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 .浏览器出于某种原因停止了它。我如何解开这篇文章被屏蔽的原因?
Chromium 24
Firefox 18
Opera 12.14

我已经验证所有浏览器都正确支持 CORS here .

通过将我的上传指向 https://cors-test.appspot.com/test ,我已经确认问题肯定出在服务器端 header 上。

最佳答案

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

  • 您确定要设置 withCredentials = true在你的 XMLHttpRequest 中?
  • 您确定您的服务器上有有效的(非自签名)SSL 证书吗?即使您添加了使用无效证书浏览站点的异常(exception),HTTPS 也可能无法通过 CORS 检查。
  • 您是否尝试清空缓存?您有 Access-Control-Max-Age: 10000在您的响应 header 中设置。那是接近3个小时。我知道您在这方面的工作时间比这更长,但是在特别测试时,将该 header 设置为零,这样您就不会因浏览器缓存旧访问权限而发疯。

  • 一般来说,我会从尽可能宽松的 CORS header 开始,然后慢慢提高安全性以查看它在哪里失败。然而,这并不完全简单。例如,根据 MDN documentation on CORS ,

    When responding to a credentialed request, server must specify a domain, and cannot use wild carding. The above example would fail if the header was wildcarded as: 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
    

    因此,您可以从那里开始并添加越来越多的安全性,直到它中断以找出罪魁祸首。

    关于nginx - 使用 CORS 的跨域分块上传,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14860282/

    相关文章:

    javascript - 如何在 AngularJS 中正确使用 HTTP.GET?具体来说,对于外部 API 调用?

    php - php检测ajax跨域请求的方法

    vue.js - Vue-cli 生产构建 - 浏览器缓存问题?

    nginx - 在 GKE 专用集群上创建入口资源时超时

    javascript - Amazon S3 CORS 配置 XMLHttpRequest GET

    image - 将文件上传到 Message Bird API

    c# - c#中php的等效代码是什么

    php - 在没有Apache的情况下将php作为服务器运行

    ruby-on-rails - 服务器 IP 更改后出现和关闭错误 324 (net::ERR_EMPTY_RESPONSE)

    javascript - 有没有办法确定在 Firebug 或网络检查器中发出 XHR 的行?