【发布时间】:2016-12-20 15:54:03
【问题描述】:
在部署在 Heroku 上的 Django 项目中,我曾经通过 boto 将文件上传到 Google 云存储。但是,最近我必须上传大文件,这会导致 Heroku 超时。
我正在关注 Heroku 关于direct file upload to S3 的文档,并进行如下自定义:
Python:
conn = boto.connect_gs(gs_access_key_id=GS_ACCESS_KEY,
gs_secret_access_key=GS_SECRET_KEY)
presignedUrl = conn.generate_url(expires_in=3600, method='PUT', bucket=<bucketName>, key=<fileName>, force_http=True)
JS:
url = 'https://<bucketName>.storage.googleapis.com/<fileName>?Signature=...&Expires=1471451569&GoogleAccessId=...'; // "presignUrl"
postData = new FormData();
postData.append(...);
...
$.ajax({
url: url,
type: 'PUT',
data: postData,
processData: false,
contentType: false,
});
我收到以下错误消息:
XMLHttpRequest cannot load http:/... Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access.
编辑:
gsutil cors get gs://<bucketName>的输出:
[{"maxAgeSeconds": 3600, "method": ["GET", "POST", "HEAD", "DELETE", "PUT"], "origin": ["*"], "responseHeader": ["Content-Type"]}]
似乎 CORS 没问题。那么,我该如何解决这个问题呢?谢谢。
编辑 2:
来自 Firefox 的 OPTION 请求的标头:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.5,en;q=0.3
Access-Control-Request-Method: PUT
Connection: keep-alive
Host: <bucketName>.storage.googleapis.com
Origin: http://localhost:8000
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:48.0) Gecko/20100101 Firefox/48.0
来自 Chrome 的 OPTION 请求的标头:
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:zh-TW,zh;q=0.8,en;q=0.6,en-US;q=0.4,zh-CN;q=0.2
Access-Control-Request-Headers:
Access-Control-Request-Method:PUT
Connection:keep-alive
Host:directupload.storage.googleapis.com
Origin:http://localhost:8000
Referer:http://localhost:8000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
X-Client-Data:CIe2yQEIprbJAQjznMoB
【问题讨论】:
-
如果您包含预检 (OPTIONS) 请求的标头和响应标头,将会有所帮助。特别是请求中的 ACCESS-CONTROL-REQUEST-* 和 ORIGIN 标头以及响应中的 ACCESS-CONTROL-* 标头。
-
您能否详细说明一下,因为我不知道如何包含这些数据。非常感谢。
-
最简单的方法是使用浏览器的开发工具(通常是 F12,但并非总是如此。例如 OS X 上的 Chrome 使用 OPTION-COMMAND-i)。开发者工具应该有一个网络标签。确保它正在捕获流量,每个浏览器都有点不同。然后继续发出您的 AJAX 请求,浏览器应该捕获传出请求和响应。如果您选择适当的请求,您应该能够看到有关来自浏览器的请求和来自服务器的响应的大量信息。
-
您收到的错误消息引用了对预检请求的响应,因此您希望获取浏览器发出的 OPTIONS HTTP 请求的 HEADER 信息。
-
我已经在
ajax对象中添加了headers: {'Access-Control-Allow-Origin': '*'},,但是还是不行。
标签: django google-cloud-storage boto