我希望网站的用户能够将文件上传到 Google 云存储
,而无需使用网络应用服务器资源,因此签名网址似乎是最佳选择。
当用户选择要上传的文件时,jquery
向 django
发送一个 GET
请求以获取签名 URL。该 URL 是使用 gsutil signurl
命令生成的。然后,Django 将签名的 URL 返回到模板,并在提交时使用签名的 URL 发送 jquery PUT
请求。
但是:
- PUT 请求失败,并显示“SignatureDoesNotMatch”。
- 使用此方法对存储对象的 GET 请求可以正常工作。
是否存在必须与 PUT 请求一起发送的必需 header ?
gsutil 命令(假设用户选择文件“map.html”)...
gsutil signurl -p notasecret -m PUT -d 10m /path/to/.p12 gs://bucket_name/map.html
jquery PUT 代码...
$.ajax( {
url: g_url,
type: 'PUT',
crossDomain: true,
success: console.log('success'),
error: function(XMLHttpRequest, textStatus, errorThrown){
alert('status:' + XMLHttpRequest.status + ', status text: ' + XMLHttpRequest.statusText);
},
data: file,
} );
g_url 看起来像...
https://storage.googleapis.com/bucket_name/map.html?GoogleAccessId=__retracted__&Expires=1408889274&Signature=rDJAZQG4MIyMupy0M8HJ17r8rkEJcAbYSWpcq084SdzRh%2BnZavTfuWl4Q%2F6ytkSkN2c2%2B4b4pPRF5eWOEOL1InRxlB5pEBedPFZPpgDrRvR9tFybtH%2BkesKLhIZ3WjJ0utzAwhl%2BgAlQY6ulvO0Djib20zcG5fkHOigpRf1xBUk%3D
最佳答案
事实证明我的问题与 CORS 有关。为了让它在 Django 1.6 上运行,我必须执行以下操作:
- 安装
django-cors-headers
并按照配置说明进行操作https://github.com/ottoyiu/django-cors-headers - 使用适当的动词在
GCS
存储桶上配置 CORS 并接受来 self 的域的请求 https://developers.google.com/storage/docs/cross-origin - 将 Django 文档中提供的
jquery
代码添加到我的模板 https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#how-it-works
随着 PUT
和 DELETE
请求开始工作。我遇到的唯一另一个问题是内容标题不兼容。因此,您需要在发送请求之前在签名网址中设置内容类型。
gsutil 命令看起来像
gsutil signurl -p notasecret -m PUT -d 10m -c 'multipart/formdata; charset=UTF-8' /path/to/.p12 gs://bucket_name/map.html
将 beforeSend 添加到 jquery 请求
beforeSend: function (request){
request.setRequestHeader("Content-Type", 'multipart/formdata; charset=UTF-8')
;},
关于jquery - GSUTIL 签名 Url PUT 到 Google Cloud Storage 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25473158/