Rob*_*ben 11 google-chrome xmlhttprequest cors google-cloud-storage
我使用XMLHttpRequest发送到服务器端创建的可恢复上传URL,将基于浏览器的可恢复上传到Google的云存储中.这在禁用Web安全性时完全正常,我在开发期间执行了此操作.
但现在在现实世界中,CORS一直在制造麻烦.我也尝试过与其他浏览器(没有成功),但坚持使用chrome进行进一步测试.
注意:fake.host条目/etc/HOSTS用于欺骗chrome以避免localhost限制.然而,我们的在线测试服务器的"真实"域也是如此.
使用普通的XMLHttpRequest调用启动请求:
var xhr = this.newXMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader('Content-Type', this.currentInputFile.type);
xhr.setRequestHeader('Content-Range', 'bytes ' + startByte + '-' + (this.currentInputFile.size - 1) + '/' + this.currentInputFile.size);
xhr.onload = function(e) {
...
};
...
if (startByte > 0) {
xhr.send(this.currentInputFile.slice(startByte));
} else {
xhr.send(this.currentInputFile);
}
Run Code Online (Sandbox Code Playgroud)
然后浏览器成功启动预检请求:
Remote Address:173.194.71.95:443
Request URL:https://www.googleapis.com/upload/storage/v1/b/my-bucket-name/o?uploadType=resumable&name=aa%20spacetestSMALL_512kb.mp4&upload_id=XXXXXXXXX
Request Method:OPTIONS
Status Code:200 OK
Run Code Online (Sandbox Code Playgroud)
请求标题:
:host:www.googleapis.com
:method:OPTIONS
:path:/upload/storage/v1/b/my-bucket-name/o?uploadType=resumable&name=aa%20spacetestSMALL_512kb.mp4&upload_id=XXXXXXXXX
:scheme:https
:version:HTTP/1.1
accept:*/*
accept-encoding:gzip,deflate
accept-language:en-US,en;q=0.8,de;q=0.6
access-control-request-headers:content-range, content-type
access-control-request-method:PUT
origin:https://fake.host
referer:https://fake.host/upload.xhtml
user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36
x-client-data:YYYYYY
Run Code Online (Sandbox Code Playgroud)
查询字符串参数
uploadType:resumable
name:aa spacetestSMALL_512kb.mp4
upload_id:XXXXXXXXX
Run Code Online (Sandbox Code Playgroud)
响应标题
access-control-allow-credentials:true
access-control-allow-headers:content-range, content-type
access-control-allow-methods:PUT
access-control-allow-origin:https://fake.host
alternate-protocol:443:quic
content-length:0
content-type:text/html; charset=UTF-8
date:Fri, 05 Sep 2014 14:11:21 GMT
server:UploadServer ("Built on Aug 18 2014 11:58:36 (1408388316)")
status:200 OK
version:HTTP/1.1
Run Code Online (Sandbox Code Playgroud)
...并启动PUT请求,直到传输完所有数据.但是之后chrome默默地记录错误而没有完成/结束请求:
XMLHttpRequest无法加载https://www.googleapis.com/upload/storage/v1/b/my-bucket-name ... XXXXXXXX.请求的资源上不存在"Access-Control-Allow-Origin"标头.因此不允许原点' https://fake.host '访问.
这是关于PUT请求的chrome日志:
Request URL:https://www.googleapis.com/upload/storage/v1/b/my-bucket-name/o?uploadType=resumable&name=aa%20spacetestSMALL_512kb.mp4&upload_id=XXXXXXXXX
Run Code Online (Sandbox Code Playgroud)
请求标题
Provisional headers are shown
Content-Range:bytes 0-3355302/3355303
Content-Type:video/mp4
Origin:https://fake.host
Referer:https://fake.host/upload.xhtml
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36
X-DevTools-Emulate-Network-Conditions-Client-Id:YYYYYYY
Run Code Online (Sandbox Code Playgroud)
请求参数
uploadType:resumable
name:aa spacetestSMALL_512kb.mp4
upload_id:XXXXXXXXX
Run Code Online (Sandbox Code Playgroud)
值得注意的是,在http://client.cors-api.appspot.com/client中添加相同的URL 并发出任何请求时,除了OPTIONS请求类型之外的所有请求都会失败.云存储api似乎只为OPTION请求发出正确的响应头,而不是PUT/POST/GET/...请求.
我做一些不可能的事情吗?有什么东西坏了吗?这是云存储API中的错误吗?我花了几个小时谷歌搜索和阅读SO答案,到目前为止没有任何运气.
目前,我可以定期检查下载是否传输了100%的数据并忽略了http请求结果,因为该文件实际上已完全上传到存储桶.但这是一个相当丑陋的解决方法,如果真正的问题可以解决,我真的不想使用它.
在请求可恢复的上传网址时,您必须包含浏览器在尝试使用该上传网址时发送的来源,否则后续上传将失败,就像问题中发生的那样(OPTIONS调用看起来不错,但是PUT将不会).
它必须与浏览器的原点完全匹配(您可以在javascript中获取location.origin).
这是本文档中"启动可恢复上传会话"的步骤:https: //cloud.google.com/storage/docs/json_api/v1/how-tos/resumable-upload
如果您在服务器端请求可恢复的上传URL,您可能需要客户端(浏览器)向您传递其来源(例如:location.origin).
fwiw我在这个步骤中使用Google的云存储库来进行python,并且需要像这样添加原点:
myblob.create_resumable_upload_session(mycontenttype, origin=browserorigin)
Run Code Online (Sandbox Code Playgroud)
请注意,您绝对不需要为您的存储桶设置CORS.
| 归档时间: |
|
| 查看次数: |
3546 次 |
| 最近记录: |