本示例讲解在服务端通过PHP代码完成签名,并且服务端设置了上传后回调,然后通过表单直传数据到OSS。

背景

采用服务端签名后直传方案有个问题:用户上传数据后,很多场景下,应用服务器需要知道用户上传了哪些文件以及文件名称,如果是图片的话,还需要知道图片的大小等。为此OSS提供了上传回调方案。OSS回调完成后,应用服务器再返回结果给客户端。这样服务端就可以实时了解用户上传了什么文件。

Demo

您可以通过样例体验服务端签名直传并设置上传回调的效果:PC浏览器测试样例

原理介绍

服务端签名直传并设置上传回调的逻辑图如下:

流程如下:
  1. 用户向应用服务器请求上传Policy和回调。
  2. 应用服务器返回上传Policy和回调设置。
  3. 用户直接向OSS发送文件上传请求。
  4. OSS根据用户的回调设置,发送回调请求给应用服务器。
  5. 应用服务器返回响应给OSS。
  6. OSS将应用服务器返回的内容返回给用户。
    说明
    如果应用服务器返回成功,那么OSS就返回成功给用户;如果应用服务器返回失败,那么OSS也返回失败给用户。这样确保了用户上传成功和失败的文件,应用服务器都会收到通知。

简单讲,就是用户要上传一个文件到OSS,而且希望上传完毕的时候自己的应用服务器能够知道这件事,这时就需要设置一个回调函数,把这件事告知用户的应用服务器。这样当OSS收到用户的上传请求之后开始上传,上传完之后不会直接给用户返回结果,而是先通知用户的应用服务器,然后再把结果转达给用户。

前提条件

  • Web服务器已部署。
  • Web服务器对应的域名可通过公网访问。

步骤 1:下载并安装Plugload

Plupload是一款简单易用且功能强大的文件上传工具, 支持多种上传方式,包括html5、flash、silverlight,、html4。它会智能检测当前环境,选择最适合的上传方式,并且会优先采用Html5方式。请参见Plupload官网进行下载和安装。

步骤 2:下载应用服务器代码

步骤 3:修改配置文件

本示例采用PHP编写。将下载包解压后,修改以下文件:
  • 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:体验上传回调

  1. 将应用服务器代码zip包解压到web根目录下。
  2. 在Web浏览器中输入<Web应用服务器地址>/oss-h5-upload-js-php-callback/index.html,例如http://abc.com:8080/oss-h5-upload-js-php-callback/index.html
  3. 选择一个或多个文件进行上传。
  4. 上传成功后,通过控制台查看上传结果。

核心代码解析

本示例的更多细节,如上传签名、设置随机文件名等请参见服务端签名直传—核心代码解析

代码要添加的内容如下:
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为例,具体设置方法如下:
  1. 打开rewrite模块,执行命令:a2enmod rewrite
  2. 修改配置文件 /etc/apache2/apache2.conf(根据apache2的安装路径不同会有不一样)。将Allow Override设置成All,然后添加以下两个配置项:
    • RewriteEngine on
    • RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]