本文主要介绍如何基于POST Policy的使用规则在客户端通过JavaScript代码完成签名,然后通过表单直传数据到OSS。

注意事项

  • 在客户端通过JavaScript代码完成签名,无需过多配置,即可实现直传,非常方便。但是客户端通过JavaScript把AccesssKey ID和AccessKey Secret写在代码里面有泄露的风险,强烈建议使用服务端签名后直传或者STS临时授权访问OSS
  • 本文档提供的应用服务器代码支持html5、flash、silverlight、html4等协议,请保证您的浏览器支持以上协议。如果提示“你的浏览器不支持flash,Silverlight或者HTML5!”,请升级您的浏览器版本。

步骤1:下载浏览器客户端代码

本示例采用Plupload直接提交表单数据(即PostObject)到OSS,可以运行于PC浏览器、手机浏览器、微信等。您可以同时选择多个文件上传,并设置上传到指定目录和设置上传文件名称是随机文件名还是本地文件名。您还可以通过进度条查看上传进度。

  1. 下载浏览器客户端代码
  2. 将下载的文件解压。
说明 示例中使用的前端插件是Plupload,您可以根据实际需求更换插件。

步骤2:修改配置文件

打开upload.js文件,修改访问配置。
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
accessid= '<yourAccessKeyId>';
accesskey= <yourAccessKeySecret>';
host= <yourHost>';

.....
new_multipart_params = {
        ....
        'OSSAccessKeyId': accessid, 
        ....
    };

//如果是STS方式临时授权访问OSS,请参见如下代码。
accessid= 'accessid';
accesskey= 'accesskey';
host = 'http://post-test.oss-cn-hangzhou.aliyuncs.com';
STS_ROLE = ''; // eg: acs:ram::1069test7698:role/all

.....
new_multipart_params = {
        ....
        'OSSAccessKeyId': STS.accessID, 
        'x-oss-security-token':STSToken,
        ....
    };
//===========
host = 'http://post-test.oss-cn-hangzhou.aliyuncs.com';
  • accessid:您的AccessKeyId。
  • accesskey:您的AcessKeySecret。
  • STS_ROLE:表示指定角色的ARN,详情请参见AssumeRole中请求参数RoleArn的说明。
  • STSToken:您的STS token。使用STS方式验证时,您需要通过STS API获取STS AccessKey ID、STS AcessKey Secret、SecurityToken,详情请参见使用STS临时访问凭证访问OSS。如果您的AccessKey ID和AccessKey Secret为阿里云账号或拥有永久权限的RAM用户AK,此项可不填。
  • host:您的OSS访问域名,格式为BucketName.Endpoint,例如post-test.oss-cn-hangzhou.aliyuncs.com。 关于OSS访问域名的介绍请参见OSS访问域名使用规则

步骤3:设置CORS

客户端进行表单直传到OSS时,会从浏览器向OSS发送带有Origin的请求消息。OSS对带有Origin头的请求消息会进行跨域规则(CORS)的验证,因此需要为Bucket设置跨域规则以支持Post方法。

  1. 登录OSS管理控制台
  2. 单击Bucket列表,之后单击目标Bucket名称。
  3. 单击权限管理 > 跨域设置,在跨域设置区域单击设置
  4. 单击创建规则,配置如下图所示。
    说明 为了您的数据安全,实际使用时, 来源建议填写实际允许访问的域名。更多配置信息请参见 设置跨域访问

步骤4:体验JavaScript客户端签名直传

  1. 在解压的客户端代码文件夹中打开index.html文件。
  2. 单击选择文件,之后选择一个或多个文件,并选择上传后的文件名命名规则及上传后文件所在目录。
  3. 单击开始上传,并等待上传完成。
  4. 上传成功后,您可以登录OSS控制台查看上传结果。

核心代码解析

因为OSS支持POST协议,所以只要在Plupload发送POST请求时带上OSS签名即可。核心代码如下:

function set_upload_param(up, filename, ret)
{
  g_object_name = g_dirname;
  if (filename != '') {
      suffix = get_suffix(filename)
      calculate_object_name(filename)
  }
  new_multipart_params = {
      'key' : g_object_name,
      'policy': policyBase64,
      'OSSAccessKeyId': accessid,
      'success_action_status' : '200', //如果不设置success_action_status为200,文件上传成功后则返回204状态码。
      'signature': signature,
  };

  up.setOption({
      'url': host,
      'multipart_params': new_multipart_params
  });

  up.start();
}
 ....

上述代码中,’key’: g_object_name表示上传后的文件路径。如果您希望上传后保持原来的文件名,请将该字段改为’key’: '${filename}'

如果您希望上传到特定目录,例如abc下,且文件名不变,请修改代码如下:

new_multipart_params = {
  'key' : 'abc/' + '${filename}',
  'policy': policyBase64,
  'OSSAccessKeyId': accessid,
  'success_action_status' : '200', //让服务端返回200,不然,默认会返回204
  'signature': signature,
};
  • 设置成随机文件名

    如果想在上传时固定设置成随机文件名,后缀保持跟客户端文件一致,可以将函数改为:

    function check_object_radio() {
        g_object_name_type = 'random_name';
    }
  • 设置成用户的文件名

    如果想在上传时固定设置成用户的文件名,可以将函数改为:

    function check_object_radio() {
        g_object_name_type = 'local_name';
    }
  • 设置上传目录

    您可以将文件上传到指定目录下。下面的代码是将上传目录改成abc/,注意目录必须以正斜线(/)结尾。

    function get_dirname()
    {
        g_dirname = "abc/"; 
    }
  • 上传签名

    上传签名主要是对policyText进行签名,最简单的例子如下:

    var policyText = {
        "expiration": "setDurationSeconds", // 为Policy指定合理的有效时长,格式为UTC时间。Policy失效后,则无法通过此Policy上传文件。
        "conditions": [
        ["content-length-range", 0, 1048576000] // 设置上传文件的大小限制。如果超过此限制,文件上传到OSS会报错。
        ]
    }

常见问题

  • 如何限制上传文件的格式?

    您可以利用Plupload的filters属性设置上传的过滤条件,例如设置上传的图片类型、上传的文件的大小等。详细代码请参见设置上传过滤条件

  • 上传后如何获取文件URL?

    您可以根据Bucket访问域名及文件访问路径获取文件的URL,详情请参见上传Object后如何获取访问URL?

  • 如何获取已上传文件的MD5值?
    您需要按F12打开开发者模式,之后开始上传文件。文件上传成功后在响应头中可以查看文件的MD5,如下图所示。

如果您还有更多问题,请提交工单寻求解答。