华为云对象存储OBSWeb端通过PostObject接口直传OBS_云淘科技

背景信息

常见的Web端上传方法是用户通过浏览器上传文件至应用服务器,再由应用服务器上传至OBS,数据需要在应用服务器中转,传输效率较低,且多任务同时上传时应用服务器压力大。

本文介绍一种在Web端利用PostObject接口直传文件至OBS的方法,即使用表单上传方式上传文件至OBS。如图1所示,该方案省去了应用服务器这一步骤,提高了传输效率,不会对服务器产生压力,且服务端签名后直传可以保证传输的安全性。

图1 Web端PostObject直传流程图

前提条件

已创建桶。具体操作请参见创建桶。

操作步骤

配置分为两大步:配置跨域资源共享和使用表单上传。

第一步:配置跨域资源共享

在通常的网页请求中,由于同源安全策略SOP的存在,不同域之间的网站脚本和内容是无法进行交互的。

跨域资源共享CORS是一种网络浏览器的规范机制,定义了一个域中加载的客户端Web应用程序与另一个域中的资源交互的方式。OBS支持CORS规范,允许跨域请求访问OBS中的资源。

在OBS管理控制台左侧导航栏选择“对象存储”。
在桶列表单击待操作的桶,进入对象页面。
在左侧导航栏,单击“访问权限控制 > CORS规则”。
单击“创建”,系统弹出“创建CORS规则”对话框,如图2所示。

一个桶最多可设置100条CORS规则。

图2 创建CORS规则

在“CORS规则”中配置“允许的来源”、“允许的方法”、“允许的头域”、“补充头域”和“缓存时间”。

若该OBS桶同时开启了CDN加速,CDN需配置HTTP header,详见HTTP header配置。

表1 CORS规则

参数

说明

配置建议

允许的来源

必选参数,指定允许的跨域请求的来源,即允许来自该域名下的请求访问该桶。

允许多条匹配规则,以回车换行为间隔。每个匹配规则允许使用最多一个“*”通配符。例如:

http://rds.example.com
https://*.vbs.example.com

*

允许的方法

必选参数,指定允许的跨域请求方法,即桶和对象的几种操作类型。包括:Get、Post、Put、Delete、Head。

全选

允许的头域

可选参数,指定允许的跨域请求的头域。只有匹配上允许的头域中的配置,才被视为是合法的CORS请求。

允许的头域可设置多个,多个头域之间换行隔开,每行最多可填写一个*符号,不支持&、:、<、空格以及中文字符。

*

补充头域

可选参数,指CORS响应中带的补充头域,给客户端提供额外的信息。

补充头域可设置多个,多个头域之间换行隔开,不支持*、&、:、<、空格以及中文字符。

ETag
x-obs-request-id
x-obs-api
Content-Type
Content-Length
Cache-Control
Content-Disposition
Content-Encoding
Content-Language
Expires
x-obs-id-2
x-reserved-indicator
x-obs-version-id
x-obs-copy-source-version-id
x-obs-storage-class
x-obs-delete-marker
x-obs-expiration
x-obs-website-redirect-location
x-obs-restore
x-obs-version
x-obs-object-type
x-obs-next-append-position

缓存时间

必选参数,请求来源的客户端可以缓存的CORS响应时间,以秒为单位,默认为100秒。

根据实际业务设置。

单击“确定”。

“CORS规则”页签显示“创建CORS规则成功”提示创建桶的CORS配置成功。CORS配置会在两分钟内生效。

CORS配置成功后,便仅允许跨域请求来源的地址通过允许的方法访问OBS的桶。例如:为桶“testbucket”允许的来源配置为“https://www.example.com”,允许的方法配置为“GET”,允许的头域和补充的头域配置为“*”,缓存时间设置为“100”,则OBS仅允许来源为“https://www.example.com”的“GET”请求访问桶“testbucket”,且不限制该请求的头域,请求来源的客户端可缓存的该CORS请求的响应时间为100秒。

第二步:使用表单上传

以BrowserJS为例,演示如何直接使用SDK计算签名。

基于表单上传是使用HTML表单形式上传对象到指定桶中,对象最大不能超过5GB。

您可以通过ObsClient.createPostSignatureSync生成基于表单上传的请求参数。使用BrowserJS代码模拟表单上传的完整代码示例,可单击此处下载:post-object-sample。您也可以通过如下步骤进行表单上传:

使用ObsClient.createPostSignatureSync生成用于鉴权的请求参数。

使用SDK生成用于鉴权的请求参数包括两个:

Policy:对应表单中policy字段。
Signature:对应表单中的signature字段。

代码示例如下:

// 创建ObsClient实例
var obsClient = new ObsClient({
    // 认证用的ak和sk硬编码到代码中或者明文存储都有很大的安全风险,建议在配置文件或者环境变量中密文存放,使用时解密,确保安全;本示例以ak和sk保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量AccessKeyID和SecretAccessKey。
    // 您可以登录访问管理控制台获取访问密钥AK/SK,获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html
    access_key_id: process.env.AccessKeyID,
    secret_access_key: process.env.SecretAccessKey,
    server : 'https://your-endpoint',
    signature : 'obs'
});

// 设置表单参数
var formParams = {
              // 设置对象访问权限为公共读
              'x-obs-acl': obsClient.enums.AclPublicRead, 
              // 设置对象MIME类型
              'content-type': 'text/plain'           
};

// 设置表单上传请求有效期,单位:秒
var expires = 3600;

var res = obsClient.createPostSignatureSync({Expires:expires, FormParams: formParams});

// 获取表单上传请求参数
console.log('	' + res.Policy);
console.log('	' + res.Signature);

准备表单HTML页面。

表单HTML代码示例如下:


<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />



<form action="http://bucketname.your-endpoint/" method="post" enctype="multipart/form-data">
Object key

<input type="text" name="key" value="objectname" />

ACL <input type="text" name="x-obs-acl" value="public-read" />

Content-Type <input type="text" name="content-type" value="text/plain" />

<input type="hidden" name="policy" value="*** Provide your policy ***" /> <input type="hidden" name="AccessKeyId" value="*** Provide your access key ***"/> <input type="hidden" name="signature" value="*** Provide your signature ***"/> <input name="file" type="file" /> <input name="submit" value="Upload" type="submit" />

HTML表单中的policy,signature的值均是从ObsClient.createPostSignatureSync的返回结果中获取。
表单HTML示例可单击此处下载:PostDemo。

将生成的请求参数填入HTML页面。
选择本地文件,进行表单上传。

知识扩展

采用BrowserJS SDK直接计算签名时,AK/SK可能会展现在前端界面,有一定风险。

您还可以采用客户端-服务端模型,服务端可以采用Java、Python等SDK计算POST上传签名,客户端采用JavaScript向服务端获取签名信息后利用签名信息访问OBS。

其中,计算POST上传签名信息请参考各SDK语言:

Java
Python
PHP
BrowserJS
Node.js

除POST上传外,在其他场景中,为了避免前端代码直接使用AK/SK访问OBS造成敏感信息泄露,可以通过后台计算临时URL,前端使用临时URL授权访问OBS。

利用GO SDK计算临时URL,前端JS使用临时URL列举OBS桶内对象。示例如下:

GO SDK后台计算列举桶临时URL。

// 引入依赖包
import (
       "fmt"
       "obs"
       "strings"
)

//推荐通过环境变量获取AKSK,这里也可以使用其他外部引入方式传入,如果使用硬编码可能会存在泄露风险。
//您可以登录访问管理控制台获取访问密钥AK/SK,获取方式请参见https://support.huaweicloud.com/usermanual-ca/ca_01_0003.html。
var ak = os.Getenv("AccessKeyID")
var sk = os.Getenv("SecretAccessKey")
var endpoint = "https://your-endpoint"

// 创建ObsClient结构体
var obsClient, _ = obs.New(ak, sk, endpoint)

func main() {
       input := &obs.CreateSignedUrlInput{}
       input.Expires = 3600

       // 生成列举对象临时URL
       // 指定为GET请求,传入桶名
       input.Method = obs.HttpMethodGet
       input.Bucket = "bucketname"
       output, _ := obsClient.CreateSignedUrl(input)
      // 获取生成的临时URL及请求头域信息
       fmt.Printf("SignedUrl:%s
", output.SignedUrl)
       fmt.Printf("ActualSignedRequestHeaders:%v
", output.ActualSignedRequestHeaders)
}

前台获取到签名URL SignedUrl及请求头域信息ActualSignedRequestHeaders后,访问OBS进行列举桶操作。

// 使用GET请求获取对象列表
var bucketName = 'bucketname';
var method = 'GET';

// SignedUrl为上一步骤中后端服务计算得到的临时URL,
// ActualSignedRequestHeaders为上一步骤中后端服务计算临时URL时使用的请求头域,前台实际请求应保持一致;
var reopt = {
       method : method,
       url : SignedUrl,
       withCredentials: false, 
       headers : ActualSignedRequestHeaders || {},
       validateStatus: function(status){
              return status >= 200;
       },
       maxRedirects : 0,
       responseType : 'text',
};

axios.request(reopt).then(function (response) {
       if(response.status < 300){                     
              console.log('Listing object using temporary signature succeed.');              
       }else{                     
              console.log('Listing object using temporary signature failed!');                     
              console.log('status:' + response.status);                     
              console.log('
');              
       }              
       console.log(response.data);              
       console.log('
');
}).catch(function (err) {
       console.log('Listing object using temporary signature failed!');       
       console.log(err);       
       console.log('
');
});

其中,生成临时授权访问URL请参考各SDK语言:

Java
Python
Go
Node.js

同意关联代理商云淘科技,购买华为云产品更优惠(QQ 78315851)

内容没看懂? 不太想学习?想快速解决? 有偿解决: 联系专家