JavaScript SDK
<p><strong>1. 简介</strong></p>
<p>JavaScript SDK 适用于 IE9+、Chrome、Firefox、Safari 等浏览器,基于平安云OBS- API 构建。开发者使用本JS-SDK 可以方便的从浏览器端上传文件至平安云OBS,并对上传成功后的图片进行下载,删除,数据处理操作。</p>
<p>本 SDK 为客户端 JavaSript SDK,没有包含 token(用户操作凭证) 生成实现,为了安全,建议您通过网络从用户的签名服务端获取token,具体生成代码请参考后面签名服务模板。</p>
<p>如果您还没有开通或者还不了解平安云 OBS 服务,请登录 OBS产品主页 进行了解。</p>
<ul>
<li><strong>上传</strong></li>
</ul>
<p>html5、Flash、html4 模式直接上传和分片上传</p>
<p>继承了 Plupload 的功能,可筛选文件上传、拖曳上传等</p>
<ul>
<li><strong>下载</strong></li>
</ul>
<p>用户通过JS SDK生成文件下载的 URL,用户访问该 URL 进行有效时间内下载。</p>
<p> </p>
<p><strong>2. SDK下载</strong></p>
<p>JavaScript SDK 开发包最新版本 <a href="https://obs-cn-shanghai.yun.pingan.com/pcp-portal/sdk%2Fobs-javascript-sdk-1.3.0.zip?response-content-disposition=attachment%3Bfilename%3Dobs-javascript-sdk-1.3.0.zip">v1.3.0</a></p>
<p> </p>
<p><strong>3. API概览</strong></p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td>
<p><strong>API</strong></p>
</td>
<td>
<p><strong>描述</strong></p>
</td>
</tr>
<tr>
<td>
<p><em>签名服务准备</em></p>
</td>
<td>
<p><em>本 SDK 依赖服务端颁发的上传凭证,可以通过网络从用户的服务端获取。</em></p>
</td>
</tr>
<tr>
<td>
<p><em>初始化</em></p>
</td>
<td>
<p><em>要接入平安云 OBS 存储,您需要拥有一对有效的 Access Key 和 Secret Key 进行签名认证。可以通过如下步骤获得:</em></p>
<p><em>开通 OBS 账号,登录 OBS 平台,查看 Access Key 和 Secret Key。</em></p>
</td>
</tr>
<tr>
<td>
<p><em>上传</em></p>
</td>
<td>
<p>上传文件</p>
</td>
</tr>
<tr>
<td>
<p><em>下载</em></p>
</td>
<td>
<p>下载文件</p>
</td>
</tr>
</tbody>
</table>
<p> </p>
<p><strong>4. API描述</strong></p>
<p><strong>(1) 签名服务准备</strong></p>
<p><strong>接口描述</strong></p>
<p>本 SDK 依赖服务端颁发的上传凭证,可以通过网络从用户的服务端获取。</p>
<p>用户服务端可以通过下面两种方式去生成签名:</p>
<ul>
<li>用户按照签名规则自行生成,详细的签名规则见 附录OBS签名文档。</li>
<li>调用 OBS JAVA SDK 中 getSign 接口去生成签名,请参考下面的代码示例去返回 JSON 数据。</li>
</ul>
<p>后端服务应提供一个 URL 地址,供 SDK 获取签名使用,前端通过 Ajax 请求该地址后获得签名。Ajax 请求成功后,服务端应返回如下格式的 json。</p>
<p><strong>示例</strong></p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="vertical-align:top">
<p>{</p>
<p>// 根据算签规则计算出的签名</p>
<p>"<strong>signature</strong>":"TjEc68iSYpmw1qRiyIrJMnOF1M=",</p>
<p>// 用户公钥</p>
<p>"<strong>AWSAccessKeyId</strong>":"TjEc68iSYpmw1qRiyIrJMnOF1M=",</p>
<p>// 当前标准格式GMT时间</p>
<p>"<strong>date</strong>":"Mon, 28 Aug 2017 02:51:10 GMT",</p>
<p>// 仅为下载URL时使用,当前时间的time值+过期的秒数,具体见附录OBS签名文档。</p>
<p>"<strong>expires</strong>":"1503889172"</p>
<p>}</p>
</td>
</tr>
</tbody>
</table>
<p>如果用户调用 OBS JAVA SDK 中 getSign 接口去生成签名,可以参考如下代码模板。</p>
<p>示例签名服务器 URL:http://xxx:8080/getSign</p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="vertical-align:top">
<p>@RequestMapping(value = "/getSign")</p>
<p>public String getSign( @RequestParam(value = "path") String path,</p>
<p>@RequestParam(value = "method") String method,</p>
<p>@RequestParam(value = "contentType", required = false) String contentType,</p>
<p>@RequestParam(value = "date", required = false) String date,</p>
<p>@RequestParam(value = "expires", required = false) String expires,</p>
<p>@RequestParam(value = "contentDisposition", required = false) String contentDisposition</p>
<p>) throws Exception {</p>
<p> </p>
<p>RadosgwService service = RadosgwServiceFactory.getFromConfigObject(new ObsClientConfig() {</p>
<p>public String getUserAgent() {</p>
<p>return "";</p>
<p>}</p>
<p>public String getObsUrl() {</p>
<p>return obsUrl;</p>
<p>}</p>
<p>public String getObsAccessKey() {</p>
<p>return "<***user Access Key ***>";</p>
<p>}</p>
<p>public String getObsSecret() {</p>
<p>return "<***user Secret Key ***>";</p>
<p>}</p>
<p>});</p>
<p> </p>
<p>AuthSignData signData = new AuthSignData();</p>
<p> </p>
<p>signData.setRequestPath(path);</p>
<p>signData.setRequestMethod(method);</p>
<p>signData.setContentType(contentType);</p>
<p> </p>
<p>if (expires == null || expires.equals("")) {</p>
<p>signData.getSignData().put("Date", date);</p>
<p>} else {</p>
<p>signData.getSignData().put("Date", expires);</p>
<p>signData.setResponseContentDisposition(contentDisposition);</p>
<p>}</p>
<p> </p>
<p>String signature = service.getSign(signData);</p>
<p> </p>
<p>JSONObject json = new JSONObject();</p>
<p>json.put("AWSAccessKeyId", "<***user Access Key ***>");</p>
<p>json.put("signature", signature);</p>
<p>json.put("date", date);</p>
<p>json.put("expires", expires);</p>
<p> </p>
<p>return json.toString();</p>
<p>}</p>
</td>
</tr>
</tbody>
</table>
<p>入参信息说明,请参考 附录的签名规则</p>
<p>对使用该 SDK 的开发者而言,请参考后面具体的操作请求去进行相应的入参信息配置。</p>
<p> </p>
<p><strong>(2) 初始化</strong></p>
<p><strong>接口描述</strong></p>
<p>要接入平安云 OBS 存储,您需要拥有一对有效的 Access Key 和 Secret Key 进行签名认证。可以通过如下步骤获得:</p>
<p>1)开通 OBS 账号</p>
<p>2)登录 OBS 平台,查看 Access Key 和 Secret Key</p>
<p>3)在页面中引入<strong> fincloud-pingan-obs-javascript-sdk-1.3.0.js</strong>。</p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="vertical-align:top">
<p><script src="fincloud-pingan-obs-javascript-sdk-1.3.0.js"></script></p>
</td>
</tr>
</tbody>
</table>
<p>4)配置用户自己的签名服务器路径, 目的:用户通过唯一的Access Key 和 Secret Key,根据签名规则,计算出用户端的签名,如果该签名和OBS服务端签名一致,那么验证通过,用户将能操作文件进行上传/下载。</p>
<p> </p>
<p><strong>(3) 上传</strong></p>
<p><strong>接口描述</strong></p>
<ul>
<li>要接入平安云 OBS在页面中引入 plupload.dev.js 和 moxie.js,可以从最新版本的压缩包中获取。</li>
<li>在页面中引入fincloud-pingan-obs-javascript-sdk-1.3.0.js</li>
<li>初始化 uploader (请确保在执行初始化时,页面已经引入 plupload):</li>
<li>分片上传默认支持一片5M,支持10000片上传。用户可以根据自己的业务需要,设置分片的大小,但一片最小必须是5M,建议最大不要超过30M。</li>
</ul>
<p><strong>示例</strong></p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="vertical-align:top">
<p>var uploader = new PaObs.uploader({</p>
<p>runtimes : 'html5,flash,html4', //上传模式,依次退化</p>
<p>browse_button : 'selectfiles', //上传选择的点选按钮,必需</p>
<p>container: 'container', //上传区域DOM ID,默认是browser_button的父元素</p>
<p>endpoint: 'obs-cn-shanghai.yun.pingan.com', //上传地址PingAn-OBS-endpoint,从平安云OBS控制台获取.</p>
<p>bucket:'user-bucket', //上传的bucket.</p>
<p>//key:'objectKey', //对象存储的key,如果key为null,将用文件名作为key.</p>
<p>//unique_names: true, //是否生成唯一的id作为对象的key.默认false,key为文件名。若开启该选项,JS-SDK会为每个文件自动生成key</p>
<p>filters: [{title: "Image files", extensions: "jpg,gif,png"},</p>
<p>{title: 'Zip files', extensions: 'zip,7z,rar'},</p>
<p>{title: 'txt files', extensions: 'txt'}</p>
<p>], //文件限制</p>
<p>resize: {</p>
<p>width: 500,</p>
<p>height: 500,</p>
<p>crop: true,</p>
<p>quality: 60,</p>
<p>preserve_headers: false</p>
<p>}, //重置图片参数</p>
<p> </p>
<p>uptoken_url:'', //签名路径,如果配置该URL,返回值将严格按照obs附件文档要求(用户服务端生成Token文档).</p>
<p>uptoken_func: function (bucket, path, method, contentType, date, contentDisposition) { //如果同时设置了uptoken_url和uptoken_func,其优先级为uptoken_url > uptoken_func</p>
<p>var requestTokenURL = 'http://<***user token server***>/getSign'</p>
<p>+ '?bucket=' + encodeURIComponent(bucket)</p>
<p>+ '&path=' + encodeURIComponent(path)</p>
<p>+ '&method=' + encodeURIComponent(method)</p>
<p>+ '&contentType=' + encodeURIComponent(contentType)</p>
<p>+ '&date=' + encodeURIComponent(date)</p>
<p>+ '&contentDisposition=' + encodeURIComponent(contentDisposition);</p>
<p> </p>
<p>var ajax = {};</p>
<p>if (window.XMLHttpRequest) {</p>
<p>ajax = new XMLHttpRequest();</p>
<p>} else {</p>
<p>ajax = new ActiveXObject("Microsoft.XMLHTTP");</p>
<p>}</p>
<p>ajax.open('GET', requestTokenURL, false);</p>
<p>ajax.send();</p>
<p>if (ajax.status == 200) {</p>
<p>var res = JSON.parse(ajax.responseText);</p>
<p>return res;</p>
<p>} else {</p>
<p>logger.error("***get uptoken failed from: ", requestTokenURL);</p>
<p>uploader.trigger('Error', {</p>
<p>status: 204,</p>
<p>response: "getUpToken failed",</p>
<p>file: file,</p>
<p>code: plupload.HTTP_ERROR</p>
<p>});</p>
<p>return '';</p>
<p>}</p>
<p>}, //如果签名路径为空,用户可以自定义自己的签名获取方式,但返回值严格按照obs的json格式.</p>
<p>init: {</p>
<p>PostInit: function () {</p>
<p>document.getElementById('obsfile').innerHTML = '';</p>
<p>document.getElementById('postfiles').onclick = function () {</p>
<p>uploader.start();</p>
<p>return false;</p>
<p>};</p>
<p>},</p>
<p> </p>
<p>FilesAdded: function (up, files) {},</p>
<p> </p>
<p>BeforeUpload: function(up, file) {},</p>
<p> </p>
<p>UploadProgress: function (up, file) {},</p>
<p> </p>
<p>FileUploaded: function (up, file, info) {},</p>
<p> </p>
<p>Error: function (up, err) {},</p>
<p> </p>
<p>UploadComplete: function() {},</p>
<p>}</p>
<p>});</p>
<p> </p>
<p>uploader.init();</p>
<p> </p>
</td>
</tr>
</tbody>
</table>
<ul>
<li>如果一个页面中有多个上传实例,可以按如下操作:</li>
</ul>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="vertical-align:top">
<p>var option1 = {</p>
<p>key : val ,</p>
<p>……</p>
<p>};</p>
<p>var uploader = PaObs.uploader(option1);</p>
<p> </p>
<p>var PaObs2 = new PaObsJsSDK();</p>
<p>var option2 = {</p>
<p>key : val ,</p>
<p>……</p>
<p>};</p>
<p>var uploader2 = PaObs2.uploader(option2);</p>
</td>
</tr>
</tbody>
</table>
<p> </p>
<p><strong>(4) 下载</strong></p>
<p><strong>接口描述</strong></p>
<ul>
<li>在页面中引入<strong>fincloud-pingan-obs-javascript-sdk-1.3.0.js</strong></li>
<li>支持公私有url下载。</li>
<li>支持参数选择缩略图下载,需要在公私有url上添加format值。</li>
</ul>
<p><strong>示例</strong></p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="vertical-align:top">
<p>// 公有url生成</p>
<p>var url = PaObs.getUrl ({</p>
<p>domain: 'bucketXXX.obs-cn-shanghai.yun.pingan.com', //下载文件时所用的加速域名,或者OBS访问域名(访问域名从用户OBS控制台获取)</p>
<p>bucket: 'bucketXXX', //下载文件的bucket</p>
<p>key: 'objectKey', //下载文件的对象key</p>
<p>format: 'imageView/0/w/500/h/500' //配置该参数去进行缩略图下载.</p>
<p>});</p>
<p>// 私有url生成</p>
<p>var url = PaObs.getUrlWithToken({</p>
<p>domain: 'bucketXXX.obs-cn-shanghai.yun.pingan.com', //下载文件时所用的加速域名,或者OBS访问域名(访问域名从用户OBS控制台获取)</p>
<p>bucket: 'bucketXXX', //下载文件的bucket</p>
<p>key: 'objectKey', //下载文件的对象key</p>
<p>downtoken_url: 'http://TokenServer/getSign', //下载文件的token获取路径.</p>
<p>//downtoken_func:'' //如果用户自定义获取token方法,请配置该参数,并将downtoken_url设置为null</p>
<p>expireSeconds: 120, //配置下载链接过期时间,以秒为单位.</p>
<p>format: 'imageView/0/w/500/h/500' //配置该参数去进行缩略图下载.</p>
<p>});</p>
</td>
</tr>
</tbody>
</table>
<p>关于format :'imageView/{mode}/w/{weight}/h/{height}/format/{imageFormat}'说明:</p>
<p>imageView是OBS API图片处理关键字。格式转换,获取适配图片,支持格式 jpeg,tiff, gif, bmp, png ,其中 gif 格式只会保留第一帧图片,此方法将占用一个 Http 连接,在 Content 读取完毕或显示关闭时释放连接。</p>
<p>mode:缩放方式,有效值 0-5</p>
<ul>
<li>0:限定缩略图的长边最多为 ,短边最多为 ,进行等比缩放,不裁剪。如果只指定 w 参数则表示限定长边(短边自适应),只指定 h 参数则表示限定短边(长边自适应)。</li>
<li>1:限定缩略图的宽最少为 ,高最少为 ,进行等比缩放,居中裁剪。转后的缩略图通常恰好是 x 的大小(有一个边缩放的时候会因为超出矩形框而被裁剪掉多余部分)。如果只指定 w 参数或只指定 h 参数,代表限定为长宽相等的正方图。</li>
<li>2:限定缩略图的宽最多为 ,高最多为 ,进行等比缩放,不裁剪。如果只指定 w 参数则表示限定宽(长自适应),只指定 h 参数则表示限定长(宽自适应)。它和模式0类似,区别只是限定宽和高,不是限定长边和短边。从应用场景来说,模式0适合移动设备上做缩略图,模式2适合PC上做缩略图。</li>
<li>3:限定缩略图的宽最少为 ,高最少为 ,进行等比缩放,不裁剪。如果只指定 w 参数或只指定 h 参数,代表长宽限定为同样的值。你可以理解为模式1是模式3的结果再做居中裁剪得到的。</li>
<li>4:限定缩略图的长边最少为 ,短边最少为 ,进行等比缩放,不裁剪。如果只指定 w 参数或只指定 h 参数,表示长边短边限定为同样的值。这个模式很适合在手持设备做图片的全屏查看(把这里的长边短边分别设为手机屏幕的分辨率即可),生成的图片尺寸刚好充满整个屏幕(某一个边可能会超出屏幕)。</li>
<li>5:限定缩略图的长边最少为 ,短边最少为 ,进行等比缩放,居中裁剪。如果只指定 w 参数或只指定 h 参数,表示长边短边限定为同样的值。同上模式4,但超出限定的矩形部分会被裁剪。 `width:` 图片宽度,非负数,有效值(0-6000)</li>
</ul>
<p> w代表width宽度,图片宽度,非负数,有效值(0-6000)</p>
<p> h代表height高度,图片高度,非负数,有效值(0-6000)</p>
<p> imageFormat:图片格式(非必传),支持jpeg, tiff, gif, bmp, png</p>
<p> </p>
<p><strong>5. 常见问题</strong></p>
<p>因为本JS-SDK主要基于 plupload,用户可以通过参阅 plupload 文档资料,可以对OBS的 demo 进行修改,以满足自己的业务需求,plupload 插件的使用文档请参阅plupload官方文档。</p>
<p><strong>(1) </strong><strong>关于上传文件命名问题</strong></p>
<p>在 upload.js 里面,unique_names 是 plupload 插件下面的一个参数,当值为 true 时会为每个上传的文件生成一个唯一的文件名,这个是 plupload 插件自动生成的,如果设置成 false,OBS会以上传的原始名进行命名。</p>
<p><strong>(2) </strong><strong>使用plupload的resize设置压缩上传,可以使用该参数对将要上传的图片进行压缩,该参数是一个对象,里面包括5个属性:</strong></p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="vertical-align:top">
<p>resize: {</p>
<p>width: 100,</p>
<p>height: 100,</p>
<p>crop: true,</p>
<p>quality: 60,</p>
<p>preserve_headers: false</p>
<p>}</p>
</td>
</tr>
</tbody>
</table>
<ul>
<li>width:指定压缩后图片的宽度,如果没有设置该属性则默认为原始图片的宽度</li>
<li>height:指定压缩后图片的高度,如果没有设置该属性则默认为原始图片的高度</li>
<li>crop:是否裁剪图片</li>
<li>quality:压缩后图片的质量,只对jpg格式的图片有效,默认为90。quality可以跟width和height一起使用,但也可以单独使用,单独使用时,压缩后图片的宽高不会变化,但由于质量降低了,所以体积也会变小</li>
<li>preserve_headers:压缩后是否保留图片的元数据,true为保留,false为不保留,默认为true。删除图片的元数据能使图片的体积减小一点。</li>
</ul>
<p><strong>(3) </strong><strong>限制上传文件的类型</strong></p>
<p>通过 plupload 中设定 filter 参数直接在 JS 前端限定,如下:</p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="vertical-align:top">
<p>filters: {</p>
<p>mime_types : [ //只允许上传图片和zip文件</p>
<p>{ title : "Image files", extensions : "jpg,gif,png" },</p>
<p>{ title : "Zip files", extensions : "zip" }</p>
<p>],</p>
<p>max_file_size : '400kb', //最大只能上传400kb的文件</p>
<p>prevent_duplicates : true //不允许选取重复文件. </p>
<p>}</p>
</td>
</tr>
</tbody>
</table>
<ul>
<li>可以使用该参数来限制上传文件的类型,大小等,该参数以对象的形式传入,它包括三个属性:<strong>mime_types:</strong>用来限定上传文件的类型,为一个数组,该数组的每个元素又是一个对象,该对象有title和extensions两个属性,title为该过滤器的名称,extensions为文件扩展名,有多个时用逗号隔开。该属性默认为一个空数组,即不做限制。</li>
<li><strong>max_file_size:</strong>用来限定上传文件的大小,如果文件体积超过了该值,则不能被选取。值可以为一个数字,单位为b,也可以是一个字符串,由数字和单位组成,如’200kb’</li>
<li><strong>prevent_duplicates:</strong>是否允许选取重复的文件,为true时表示不允许,为false时表示允许,默认为false。如果两个文件的文件名和大小都相同,则会被认为是重复的文件</li>
</ul>
<p><strong>(4) </strong><strong>设置每次只能选择一个文件</strong></p>
<p>通过 plupload 插件中的 multi_selection 参数控制,如下:</p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="vertical-align:top">
<p>multi_selection: false</p>
</td>
</tr>
</tbody>
</table>
<p><strong>(5) </strong><strong>设置取消上传,暂停上传</strong></p>
<p>在 index.html 中加入两个控制按钮:</p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="vertical-align:top">
<p>uploader.stop();</p>
</td>
</tr>
</tbody>
</table>
<p><strong>(6) </strong><strong>分片上传</strong></p>
<p>目前JS SDK支持直传和分片上传.</p>
<p> 当设置上传参数chunk_size:'0'的时候,上传方式为直传.</p>
<p> 当未设置上传参数chunk_size的时候,上传文件大于5M,默认分片上传,每片为5M.</p>
<p><strong>(7) </strong><strong>关于请求 token 出现跨域</strong></p>
<p>因为都是建议用户从后端 SDK 获取 token,然后在 upload.js 里设置参数 uptoken_url:'获取uptoken的url',这里就有可能出现跨域的现象,此时在服务端添加 response.setHeader("Access-Control-Allow-Origin","*"); 相应头字段即可。</p>
<p><strong>(8) </strong><strong>关于多个按钮选择文件的 Demo</strong></p>
<p>很多用户都在问 JSSDK 多文件选择的 Demo,其实只需要在 upload.js 文件里多 new 几个 Uploader 对象,然后在主页上写好对应的上传按钮就可以了。upload.js 里面多 new 几个 uploader 对象。</p>
<p> </p>
<p><strong>6. 附录:签名规则</strong></p>
<p>签名是系统根据签名规则生成出来的字符串,用于判断客户端和服务端生成的签名是否一致,以此来判断用户是否有权限在OBS进行操作。</p>
<p>用户签名分为:Header签名和URL签名.</p>
<p>Header签名: 用户可以在HTTP请求中增加 Authorization 的 Header 来包含签名(Signature)信息,表明这个消息已被授权。</p>
<p>URL签名:除了使用 Authorization Head,用户还可以在URL中加入签名信息,这样用户就可以把该URL转给第三方实现授权访问, 并且可以设置过期时间等。</p>
<p>Header 签名</p>
<p>用户可以在HTTP请求中增加 Authorization 的 Header 来包含签名(Signature)信息,表明这个消息已被授权。</p>
<p>Authorization 字段计算的方法:</p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="vertical-align:top">
<p>Authorization <strong>=</strong> "AWS " <strong>+</strong> AccessKeyId <strong>+</strong> ":" <strong>+</strong> Signature</p>
<p> </p>
<p>Signature <strong>=</strong> base64(hmacSha1(AccessKeySecret,</p>
<p>VERB <strong>+</strong> "\n"</p>
<p><strong>+</strong> Content_MD5 <strong>+</strong> "\n"</p>
<p><strong>+</strong> Content_Type <strong>+</strong> "\n"</p>
<p><strong>+</strong> Date <strong>+</strong> "\n"</p>
<p><strong>+</strong> CanonicalizedResource))</p>
</td>
</tr>
</tbody>
</table>
<ul>
<li>AccessKeySecret 表示签名所需的密钥</li>
<li>VERB 表示HTTP 请求的 Method,主要有 PUT,GET,POST,HEAD,DELETE 等</li>
<li>\n 表示换行符</li>
<li>Content_MD5 表示请求内容数据的MD5值,对消息内容(不包括头部)计算MD5值获得128比特位数字,对该数字进行base64编码而得到。该请求头可用于消息合法性的检查(消息内容是否与发送时一致),如”eB5eJF1ptWaXm4bijSPyxw==”,也可以为空。为了避免影响性能,JS-SDK目前Content-MD5为null。</li>
<li>Content_Type 表示请求内容的类型,如” application/x-www-form-urlencoded”,如果是POST请求,该值为“multipart/form-data”</li>
<li>Date 表示此次操作的时间,且必须为GMT格式,如”Sun, 22 Nov 2015 08:16:38 GMT”</li>
<li>CanonicalizedResource 表示用户想要访问的 OBS 资源</li>
</ul>
<p>其中,Date 和 CanonicalizedResource 不能为空;如果请求中的 Dat e时间和 OBS 服务器的时间差 15 分钟以上,OBS 服务器将拒绝该服务,并返回 HTTP 403 错误。</p>
<p>URL签名</p>
<p>除了使用 Authorization Head,用户还可以在URL中加入签名信息,这样用户就可以把该URL转给第三方实现授权访问,并且设置过期时间等。</p>
<p>URL签名示例:</p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="vertical-align:top">
<p>http://obs.pingan.com.cn/xiaoming-bucket-0009/aaa?AWSAccessKeyId=sk-xiaoming009&Expires=1503903538&Signature=s5rmkBZ1DvkQRplG5GJ7HGd%2Fzik%3D&response-content-disposition=test.jpg</p>
</td>
</tr>
</tbody>
</table>
<p>URL签名,必须至少包含Signature,Expires,AWSAccessKeyId三个参数</p>
<ul>
<li>Expires 这个参数的值是一个UNIX时间(自UTC时间1970年1月1号开始的秒数,详见wiki),用于标识该URL的超时时间。如果OSS接收到这个URL请求的时候晚于签名中包含的Expires参数时,则返回请求超时的错误码。例如:当前时间是1141889060,开发者希望创建一个60秒后自动失效的URL,则可以设置Expires时间为1141889120。</li>
<li>AWSAccessKeyId即密钥中的AccessKeyId。</li>
<li>Signature 表示签名信息。所有的OBS支持的请求和各种Header参数,在URL中进行签名的算法和在Header中包含签名的算法基本一样。</li>
</ul>
<p>Authorization 字段计算的方法</p>
<table border="1" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="vertical-align:top">
<p>Signature <strong>=</strong> urlencode(base64(hmacSha1(AccessKeySecret,</p>
<p>VERB <strong>+</strong> "\n"</p>
<p><strong>+</strong> CONTENT_MD5 <strong>+</strong> "\n"</p>
<p><strong>+</strong> CONTENT_TYPE <strong>+</strong> "\n"</p>
<p><strong>+</strong> EXPIRES <strong>+</strong> "\n"</p>
<p><strong>+</strong> CanonicalizedResource)))</p>
</td>
</tr>
</tbody>
</table>
<p>其中,与header中包含签名相比主要区别如下:</p>
<ul>
<li>通过URL包含签名时,之前的Date参数换成Expires参数。</li>
<li>不支持同时在URL和Head中包含签名。</li>
<li>如果传入的Signature,Expires,AWSAccessKeyId出现不止一次,以第一次为准。</li>
<li>请求先验证请求时间是否晚于Expires时间,然后再验证签名。</li>
<li>将签名字符串放到url时,注意要对url进行urlencode</li>
</ul>
<p>具体的计算签名的开源代码,请参考 OBS JAVA SDK 的 getSign 接口。</p>
提交成功!非常感谢您的反馈,我们会继续努力做到更好!