本文主要介绍如何基于POST Policy的使用规则在客户端通过JavaScript代码完成签名,然后通过表单直传数据到OSS。
注意事项
- 在客户端通过JavaScript代码完成签名,无需过多配置,即可实现直传,非常方便。但是客户端通过JavaScript把AccesssKey ID和AccessKey Secret写在代码里面有泄露的风险,强烈建议使用服务端签名后直传或者STS临时授权访问OSS。
- 本文档提供的应用服务器代码支持html5、flash、silverlight、html4等协议,请保证您的浏览器支持以上协议。如果提示“你的浏览器不支持flash,Silverlight或者HTML5!”,请升级您的浏览器版本。
步骤1:下载浏览器客户端代码
本示例采用Plupload直接提交表单数据(即PostObject)到OSS,可以运行于PC浏览器、手机浏览器、微信等。您可以同时选择多个文件上传,并设置上传到指定目录和设置上传文件名称是随机文件名还是本地文件名。您还可以通过进度条查看上传进度。
- 下载浏览器客户端代码。
- 将下载的文件解压。
步骤2:修改配置文件
- 修改访问配置。
打开upload.js文件后,您可以通过以下两种方式修改访问配置。
-
通过阿里云RAM用户
// 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。 accessid= 'yourAccessKeyId'; accesskey= 'yourAccessKeySecret'; // 填写OSS访问域名,格式为
BucketName.Endpoint
,例如http://examplebucket.oss-cn-hangzhou.aliyuncs.com
。 host= 'yourHost'; ..... new_multipart_params = { .... 'OSSAccessKeyId': accessid, .... }; -
通过STS服务
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。 accessid= 'yourAccessKeyId'; accesskey= 'yourAccessKeySecret'; // 填写OSS访问域名,格式为
BucketName.Endpoint
,例如http://examplebucket.oss-cn-hangzhou.aliyuncs.com
。 host = 'http://examplebucketbucket.oss-cn-hangzhou.aliyuncs.com'; // 填写指定角色的ARN,例如acs:ram::137918634953****:role/test。 STS_ROLE = ''; ..... new_multipart_params = { .... 'OSSAccessKeyId': STS.accessid, // 从STS服务获取的安全令牌(SecurityToken)。 'x-oss-security-token':STSToken, .... };- 关于角色ARN的更多信息,请参见AssumeRole。
- 关于获取STS返回的临时访问密钥和安全令牌的具体步骤,请参见使用STS临时访问凭证访问OSS。
-
- 修改policyText配置,修改过期时间(expiration)和上传文件大小范围(content-length-range)。
更多信息,请参见附录:Post Policy。
var policyText = { "expiration": "2023-12-01T12:00:00.000Z", // 设置Policy的有效期,格式为UTC时间。如果Policy失效,将无法上传文件。 "conditions": [ ["content-length-range", 0, 1048576000] // 限制上传文件的大小,单位为字节,此处限制文件大小为1 GB。如果上传的文件大小超过此限制,文件将无法上传到OSS。如果未设置该限制,则默认文件大小最大为5 GB。 ] }
步骤3:设置CORS
客户端进行表单直传到OSS时,会从浏览器向OSS发送带有Origin
的请求消息。鉴于OSS对带有Origin
头的请求消息会进行跨域规则(CORS)的验证,您需要为Bucket设置跨域规则以支持Post方法。
步骤4:体验JavaScript客户端签名直传
- 在解压的客户端代码文件夹中打开index.html文件。
- 单击选择文件,选择一个或多个文件,然后选择上传后的文件名命名规则及上传后文件所在目录。
- 单击开始上传,并等待上传完成。
- 上传成功后,您可以登录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 = {
'OSSAccessKeyId': accessid,
'key' : g_object_name,
'policy': policyBase64,
'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 = {
'OSSAccessKeyId': accessid,
'key': 'abc/' + '${filename}',
'policy': policyBase64,
'success_action_status' : '200', // 如果不设置success_action_status为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/"; }
常见问题
- 如何限制上传文件的格式?
您可以利用Plupload的filters属性设置上传的过滤条件,例如设置上传的图片类型、上传的文件的大小等。详细代码请参见设置上传过滤条件。
- 上传后如何获取文件URL?
您可以根据Bucket访问域名及文件访问路径获取文件的URL,详情请参见如何获取单个或多个文件的URL?
- 如何获取已上传文件的MD5值?
您需要按F12打开开发者模式,之后开始上传文件。文件上传成功后在响应头中可以查看文件的MD5,如下图所示。