CORS是什么?其实OSS一直官方文档也没有说清楚。PostObject怎么用官方也一直没有代码示例。
发现有两篇文章解释了下:
一篇是英文的,来自于:
http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
一篇是中文的,来自于:
利用跨域资源共享(CORS)实现ajax跨域调用
http://blogread.cn/it/article/3542?f=wb
如果用浏览器使用JS进行表单上传(PostObject)的时候会发生什么事情?
主要经历了以下几个步骤:
1. 发OPTIONS请求给OSS,如果这个时候OSS响应403,则上传终止
2. 如果通过了OPTIONS请求,才会进行真正的PostObject
所以本文介绍从创建bucket开始到设置CORS,到通过浏览器以表单的形式直接上传到OSS。
前提条件:
假设你已经有了OSS的ID和KEY,并且本地有一个HTTP Server
第一步:
下载osscmd,需要python的环境,osscmd下载及使用具体见:
http://docs.aliyun.com/?spm=5176.383663.9.4.DrXKYw#/oss/sdk/sdk-download&python
第二步:
创建bucket,假设你已经会使用了osscmd,并且已经使用python osscmd config --host=oss-cn-hangzhou.aliyuncs.com --id=xxx --key=xxx 配置好你的HOST,ID和KEY。这里xxx需要替换成OSS实际的ID和KEY,可以从控制台的右上角的钥匙图标获取。
本文以cors-test bucket为例子,你需要替换成一个不重名的bucket
已经执行config的,请使用 python osscmd cb cors-test 创建bucket
如果没有执行config,请使用python osscmd cb cors-test --host=oss-cn-hangzhou.aliyuncs.com --id=xxx --key=xxx
也可通过官方的控制台创建bucket。
记下创建的bucket和host。
如果是控制台创建,青岛的bucket host为oss-cn-qingdao.aliyuncs.com,杭州的bucket host为oss-cn-hangzhou.aliyuncs.com
第三步:
下载代码,
并将ID,KEY,BUCKET,HOST换成自己实际使用的ID,KEY, BUCKET和HOST使用第二步创建的bucket和使用的host。
放入到HTTP Server的服务目录里,例如我的放在/var/www/html/test/postobject
然后通过浏览器上传http://10.101.166.53/test/post_object_to_oss.html
请注意,
如图所示,在我的代码中我分别将BUCKET,HOST替换成cors-test, 和oss-cn-hangzhou.aliyuncs.com。ID和KEY都替换成自己的。
这个时候如果直接上传会发现失败,查看HTTP头部如图所示,会发现403。这是因为新创建的bucket没有进行任何CORS相关的测试。
使用chrome浏览器自带的开发者工具查看http头的方法
1.在网页任意地方右击
选择审查元素或者按下 shift+ctrl+c, 打开chrome自带的调试工具;
2.
选择network标签,
刷新网页(在打开调试工具的情况下刷新);
3.刷新后在左边找到该网页url,点击 后
右边选择headers,就可以看到当前网页的http头了;
需要注意的是:
浏览器发送了
Request Method:OPTIONS 并且还发送了如下几个Header,
- Access-Control-Request-Headers:content-type
- Access-Control-Request-Method:POST
- Host:cors-test.oss-cn-hangzhou.aliyuncs.com
- Origin:http://10.101.166.53
使用getcors命令的时候发现,没有设置CORS
$osscmd getcors oss://cors-test
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>NoSuchCORSConfiguration</Code>
<Message>The CORS Configuration does not exist.</Message>
<BucketName>cors-test</BucketName>
<RequestId>54DB99D844F4D8594D991B50</RequestId>
<HostId>cors-test.oss-cn-hangzhou.aliyuncs.com</HostId>
</Error>
Error Status:
404
getcors Failed!
第四步:
根据第三步浏览器中发送的Header,设置CORS
例如设置成:
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>http://10.101.166.53</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
保存在cors.xml
为什么要这么设置?
因为第三步浏览器发送了
Origin:http://10.101.166.53,所以需要设置<AllowedOrigin>http://10.101.166.53</AllowedOrigin>
因为浏览器发送
Access-Control-Request-Method:POST,所以需要设置<AllowedMethod>POST</AllowedMethod>,
因为浏览器发送
Access-Control-Request-Headers:content-type,所以需要设置<AllowedHeader>*</AllowedHeader>
如何设置?
osscmd putcors oss://cors-test cors.xml
也可以通过控制台去设置,这里不多说
如何检查设置成功?
如果运行
$osscmd getcors oss://cors-test
出现如下的响应则表示成功
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>http://10.101.166.53</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
第五步:
重新使用浏览器上传,发现此时已经成功
如图
查看HTTP头部会发现一次OPTIONS请求,一次PostObject请求
由于代码中object的name为
var key = "events/" + (new Date).getTime() + '-' + file.name;
所以用osscmd可以查看bucket中已经上传的object
$osscmd ls oss://cors-test/events/
prefix list is:
object list is:
2015-02-12 01:05:01 48.71KB Standard oss://cors-test/events/1423674299912-Snip20150204_4.png
有几点要说明下:
1. JS的代码实际是来自于互联网,已经忘记了出处,如果有侵犯你的利益,请联系,我会删除掉。
2. 这只是一个Sample,ID和KEY是直接写在代码中的,肯定不能直接用于生产,需要做些安全处理。
PostObject其实是一个很有用的功能,尤其是对网站用户。比如找工作的网站可以让网站的用户将简历上传到OSS,而无需经过网站的服务器,大大减少对网站服务器的流量压力。