本示例讲解在服务端通过PHP代码完成签名,并且服务端设置了上传后回调,然后通过表单直传数据到OSS。
背景
采用服务端签名后直传方案有个问题:用户上传数据后,很多场景下,应用服务器需要知道用户上传了哪些文件以及文件名称,如果是图片的话,还需要知道图片的大小等。为此OSS提供了上传回调方案。OSS回调完成后,应用服务器再返回结果给客户端。这样服务端就可以实时了解用户上传了什么文件。
Demo
您可以通过样例体验服务端签名直传并设置上传回调的效果:PC浏览器测试样例
原理介绍
- 用户向应用服务器请求上传Policy和回调。
- 应用服务器返回上传Policy和回调设置。
- 用户直接向OSS发送文件上传请求。
- OSS根据用户的回调设置,发送回调请求给应用服务器。
- 应用服务器返回响应给OSS。
- OSS将应用服务器返回的内容返回给用户。
说明 如果应用服务器返回成功,那么OSS就返回成功给用户;如果应用服务器返回失败,那么OSS也返回失败给用户。这样确保了用户上传成功和失败的文件,应用服务器都会收到通知。
简单讲,就是用户要上传一个文件到OSS,而且希望上传完毕的时候自己的应用服务器能够知道这件事,这时就需要设置一个回调函数,把这件事告知用户的应用服务器。这样当OSS收到用户的上传请求之后开始上传,上传完之后不会直接给用户返回结果,而是先通知用户的应用服务器,然后再把结果转达给用户。
前提条件
- Web服务器已部署。
- Web服务器对应的域名可通过公网访问。
步骤 1:下载并安装Plugload
Plupload是一款简单易用且功能强大的文件上传工具, 支持多种上传方式,包括html5、flash、silverlight,、html4。它会智能检测当前环境,选择最适合的上传方式,并且会优先采用Html5方式。请参见Plupload官网进行下载和安装。
步骤 2:下载应用服务器代码
步骤 3:修改配置文件
- php/get.php文件:
$id= '<yourAccessKeyId>'; $key= <yourAccessKeySecrety'; $host = 'http://post-test.oss-cn-hangzhou.aliyuncs.com'; $callbackUrl = "http://oss-demo.aliyuncs.com:23450"; $callback_param = array('callbackUrl'=>$callbackUrl, 'callbackBody'=>'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}', 'callbackBodyType'=>"application/x-www-form-urlencoded");
- $id:您的AccessKeyId
- $key:您的AessKeySecret
- $host:格式为
BucketName.Endpoint
,例如post-test.oss-cn-hangzhou.aliyuncs.com
说明 关于Endpoint的介绍,请参见Endpoint(访问域名)。 - $callbackUrl:设置回调URL,即回调服务器地址,用于处理应用服务器与OSS之前的通信。例如
http://abc.com:8080/callback.php
。OSS会在文件上传完成后,把文件上传信息通过此回调URL发送给应用服务器。 - $callback_param:可选参数,用于设置callbackBody和callbackBodyType等选项。
- upload.js文件
将变量severUrl改成服务器部署的地址,用于处理浏览器和应用服务器之间的通信。例如
http://abc.com:8080/oss-h5-upload-js-php-callback/get.php
。
步骤 4:设置CORS
HTML表单直接上传到OSS会产生跨域请求。为了浏览安全,需要为Bucket设置跨域规则(CORS),支持Post方法。
具体操作步骤请参见设置跨域访问。设置如下图所示:
说明 | |
在低版本IE浏览器,Plupload会以Flash方式执行。您需要设置crossdomain.xml ,设置方法请参见OSS Web直传—使用Flash上传。 |
步骤 5:设置上传回调解析
示例程序只是完成了如何检查应用服务器收到的签名, 您需要自行增加对应用服务器收到的回调内容的格式解析 。
- PHP:
- 应用服务器回调程序代码:下载地址
- 运行方法:将解压包部署到Apache环境下,因为PHP本身语言的特点,某些数据头部的获取会依赖于环境。请参考例子根据实际环境进行修改。
- Java:
- 应用服务器回调程序代码:下载地址
- 运行方法:解压后运行
java -jar oss-callback-server-demo.jar 9000
。9000为运行的端口,可以自己指定。说明 这个jar例子在java 1.7运行通过,如果有问题可以自己依据提供的代码进行修改。这是一个maven项目。
- Python:
- 应用服务器回调程序代码:下载地址
- 运行方法:解压后直接运行python callback_app_server.py即可,程序自实现了一个简单的http server,运行该程序可能需要安装rsa的依赖。
- Ruby:
- 应用服务器回调程序代码:下载地址
- 运行方法: ruby aliyun_oss_callback_server.rb
步骤 6:体验上传回调
- 将应用服务器代码zip包解压到web根目录下。
- 在Web浏览器中输入
<Web应用服务器地址>/oss-h5-upload-js-php-callback/index.html
,例如http://abc.com:8080/oss-h5-upload-js-php-callback/index.html
。 - 选择一个或多个文件进行上传。
- 上传成功后,通过控制台查看上传结果。
核心代码解析
本示例的更多细节,如上传签名、设置随机文件名等请参见服务端签名直传—核心代码解析。
new_multipart_params = {
'key' : key + '${filename}',
'policy': policyBase64,
'OSSAccessKeyId': accessid,
'success_action_status' : '200', //让服务端返回200,不设置则默认返回204
'callback': callbackbody,
'signature': signature,
};
上述的callbackbody
是PHP服务端返回的。在本例中,从PHP服务端获取到的内容如下:
{"accessid":"6MKOqxGiGU4AUk44",
"host":"http://post-test.oss-cn-hangzhou.aliyuncs.com",
"policy":"eyJleHBpcmF0aW9uIjoiMjAxNS0xMS0wNVQyMDo1MjoyOVoiLCJjdb25kaXRpb25zIjpbWyJjdb250ZW50LWxlbmd0aC1yYW5nZSIsMCwxMDQ4NTc2MDAwXSxbInN0YXJ0cy13aXRoIiwiJGtleSIsInVzZXItZGlyXC8iXV19",
"signature":"VsxOcOudxDbtNSvz93CLaXPz+4s=",
"expire":1446727949,
"callback":"eyJjYWxsYmFja1VybCI6Imh0dHA6Ly9vc3MtZGVtby5hbGl5dW5jcy5jdb206MjM0NTAiLCJjYWxsYmFja0hvc3QiOiJvc3MtZGVtby5hbGl5dW5jcy5jdb20iLCJjYWxsYmFja0JvZHkiOiJmaWxlbmFtZT0ke29iamVjdH0mc2l6ZT0ke3NpemV9Jm1pbWVUeXBlPSR7bWltZVR5cGV9JmhlaWdodD0ke2ltYWdlSW5mby5oZWlnaHR9JndpZHRoPSR7aW1hZ2VJdbmZvLndpZHRofSIsImNhbGxiYWNrQm9keVR5cGUiOiJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQifQ==","dir":"user-dirs/"}
上面提到callbackbody
,就是上述返回结果里面的callback
内容经过base64编码后生成的。
解码后的内容如下:
{"callbackUrl":"http://oss-demo.aliyuncs.com:23450",
"callbackHost":"oss-demo.aliyuncs.com",
"callbackBody":"filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}",
"callbackBodyType":"application/x-www-form-urlencoded"}
内容解析如下:
- CallbackUrl:OSS往这个机器发送的URL请求。
- callbackHost:OSS发送这个请求时,请求头部所带的Host头。
- callbackBody:OSS请求时,发送给应用服务器的内容,可以包括文件的名称、大小、类型。如果是图片,可以是图片的高度、宽度。
- callbackBodyType:请求发送的Content-Type。
说明 | |
您的应用服务器收到的回调请求有可能没有Authotization头,这是因为有些 Web应用服务器会将Authorization头自行解析掉,比如apache2,因此需要设置成不解析这个头部。以apache2为例,具体设置方法如下:
|