如何在微信小程序环境下将文件上传到OSS 您所在的位置:网站首页 Oss对象存储存路径 如何在微信小程序环境下将文件上传到OSS

如何在微信小程序环境下将文件上传到OSS

2023-11-05 21:50| 来源: 网络整理| 查看: 265

背景信息

小程序是当下比较流行的移动应用,例如大家熟知的微信小程序、支付宝小程序等。小程序是一种全新的开发模式,无需下载和安装,为终端用户提供更优的用户体验。如何在小程序环境下上传文件到OSS也成为开发者比较关心的一个问题。

与JavaScript客户端直传实践的原理相同,小程序上传文件到OSS也是利用OSS提供的PostObject接口来实现表单文件上传到OSS。关于PostObject的详细介绍,请参见PostObject。

步骤1:配置Bucket跨域访问

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

登录OSS管理控制台。

单击Bucket 列表,然后单击目标Bucket名称。

在左侧导航栏,选择数据安全 > 跨域设置

跨域设置页面,单击创建规则,配置如下图所示。

重要

为了您的数据安全,实际使用时建议将来源填写为实际允许访问的域名。更多信息。请参见设置跨域访问。

单击确定

步骤2:微信小程序配置域名白名单

您可以为微信小程序配置域名白名单,以实现微信小程序和OSS Bucket之间的正常通信。

登录OSS管理控制台。

单击Bucket 列表,然后单击目标Bucket名称。

在存储空间概览页面的访问端口区域,查看Bucket域名

登录微信小程序平台,将上传和下载的合法域名填写为Bucket的外网访问域名。

说明

实际业务中,建议您将OSS提供的外网域名和您自己的域名进行绑定,以便使用自定义域名访问OSS存储空间中的文件。配置步骤,请参见绑定自定义域名。

步骤3:获取签名

为了您的数据安全,建议使用签名方式上传文件。OSS提供服务端签名和客户端签名两种签名方式。

服务端签名

使用服务端签名时,您需要先搭建一个签名服务,然后由客户端调用签名服务生成签名。

服务端签名源码

uploadOssHelper.js代码如下:

说明

使用代码前,您需要先安装Node.js SDK。更多信息,请参见Node.js安装。

const crypto = require("crypto-js"); class MpUploadOssHelper { constructor(options) { this.accessKeyId = options.accessKeyId; this.accessKeySecret = options.accessKeySecret; // 限制参数的生效时间,单位为小时,默认值为1。 this.timeout = options.timeout || 1; // 限制上传文件的大小,单位为MB,默认值为10。 this.maxSize = options.maxSize || 10; } createUploadParams() { const policy = this.getPolicyBase64(); const signature = this.signature(policy); return { OSSAccessKeyId: this.accessKeyId, policy: policy, signature: signature, }; } getPolicyBase64() { let date = new Date(); // 设置policy过期时间。 date.setHours(date.getHours() + this.timeout); let srcT = date.toISOString(); const policyText = { expiration: srcT, conditions: [ // 限制上传文件大小。 ["content-length-range", 0, this.maxSize * 1024 * 1024], ], }; const buffer = Buffer.from(JSON.stringify(policyText)); return buffer.toString("base64"); } signature(policy) { return crypto.enc.Base64.stringify( crypto.HmacSHA1(policy, this.accessKeySecret) ); } } module.exports = MpUploadOssHelper;

服务端接口示例

以Express为例,接口代码如下:

const express = require("express"); const app = express(); const MpUploadOssHelper = require("./uploadOssHelper.js"); app.get("/getPostObjectParams", (req, res) => { const mpHelper = new MpUploadOssHelper({ // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 accessKeyId: process.env.OSS_ACCESS_KEY_ID, accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET, // 限制参数的生效时间,单位为小时,默认值为1。 timeout: 1, // 限制上传文件大小,单位为MB,默认值为10。 maxSize: 10, }); // 生成参数。 const params = mpHelper.createUploadParams(); res.json(params); });

客户端签名

使用客户端签名时,您需要先在服务端搭建一个STS服务,然后由客户端获取STS临时授权账号并生成签名。

服务端搭建STS服务

const STS = require("ali-oss").STS; const express = require("express"); const app = express(); const stsClient = new STS({ // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 accessKeyId: process.env.OSS_ACCESS_KEY_ID, accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET, // 填写Bucket名称。 bucket: "YourBucketName", }); async function getToken() { // 指定角色的ARN,格式为acs:ram::$accountID:role/$roleName。 const STS_ROLE = "yourStsRole"; const STSpolicy = { Statement: [ { Action: ["oss:*"], Effect: "Allow", Resource: ["acs:oss:*:*:*"], }, ], Version: "1", }; const result = await stsClient.assumeRole( STS_ROLE, STSpolicy, 3600 // STS过期时间,单位为秒。 ); const { credentials } = result; return credentials; } app.get("/getToken", async (req, res) => { // 获取STS。 const credentials = await getToken(); console.log(credentials.AccessKeyId); console.log(credentials.AccessKeySecret); console.log(credentials.SecurityToken); res.json(credentials); });说明

STSpolicy包含版本号(Version)和授权语句(Statement)。每条授权语句又包含授权效力(Effect)、操作(Action)、资源(Resource)。更多信息,请参见RAM Policy概述。

客户端获取STS临时访问凭证并生成签名

import crypto from 'crypto-js'; import { Base64 } from 'js-base64'; // 计算签名。 function computeSignature(accessKeySecret, canonicalString) { return crypto.enc.Base64.stringify(crypto.HmacSHA1(canonicalString, accessKeySecret)); } const date = new Date(); date.setHours(date.getHours() + 1); const policyText = { expiration: date.toISOString(), // 设置policy过期时间。 conditions: [ // 限制上传大小。 ["content-length-range", 0, 1024 * 1024 * 1024], ], }; async function getFormDataParams() { const credentials = await axios.get('/getToken') const policy = Base64.encode(JSON.stringify(policyText)) // policy必须为base64的string。 const signature = computeSignature(credentials.AccessKeySecret, policy) const formData = { OSSAccessKeyId: credentials.AccessKeyId, signature, policy, 'x-oss-security-token': credentials.SecurityToken } return formData }步骤4:使用微信小程序上传

使用uploadFile接口上传文件,示例代码如下:

const host = ''; const signature = ''; const ossAccessKeyId = ''; const policy = ''; const key = ''; const securityToken = ''; const filePath = ''; // 待上传文件的文件路径。 wx.uploadFile({ url: host, filePath: filePath, name: 'file', // 必须填file。 formData: { key, policy, OSSAccessKeyId: ossAccessKeyId, signature, // 'x-oss-security-token': securityToken // 使用STS签名时必传。 }, success: (res) => { if (res.statusCode === 204) { console.log('上传成功'); } }, fail: err => { console.log(err); } });

参数

是否必选

说明

host

填写访问域名,且必须携带https。支持以下两种类型的访问域名:

Bucket访问域名,例如https://examplebucket.oss-cn-zhangjiakou.aliyuncs.com。

自定义域名。该自定义域名需绑定目标Bucket。

signature

填写步骤3中获取到的signature信息。

ossAccessKeyId

填写您的AccessKey ID。如果您是通过STS获取的临时用户,则填写临时用户的AccessKey ID。

policy

填写步骤3中获取到的policy信息。

key

设置文件上传至OSS后的文件路径。例如,您需要将myphoto.jpg上传至test文件夹下,则填写test/myphoto.jpg。

securityToken

如果使用STS认证,则填写步骤3中使用客户端签名获取到的SecurityToken。

filePath

填写待上传文件的本地完整路径,例如D:\example.txt。

常见问题

iOS系统使用微信小程序直传后,返回的结果中,为什么ETag参数名称会变为Etag?

问题原因:使用微信小程序直传后,OSS会返回标准的ETag。但是iOS系统的微信小程序会将返回的ETag转成了Etag,导致客户端调用ETag参数的业务出现问题。

解决方案:若您的业务涉及多个系统的微信小程序直传场景,建议您将Header中的所有参数名都转成小写进行兼容。

上传成功后,如何获取文件URL?

具体操作,请参见使用文件URL分享文件

PostObject请求时,报错The bucket POST must contain the specified 'key'. If it is specified, please check the order of the fields.怎么办?

问题原因:没有指定key表单域。

解决方案:PostObject请求时必须指定key表单域。更多信息,请参见PostObject。

微信小程序是否支持同时上传多个文件?

不支持,单次调用PostObject接口仅支持上传一个文件。如果您希望通过微信小程序上传多个文件,请循环调用PostObject接口。

OSS SDK是否支持微信小程序直传?

不支持。微信小程序直传基于微信小程序API实现,与OSS SDK无关。

微信小程序是否支持断点续传?

OSS基于微信的uploadFile接口上传文件,该接口不支持断点续传。

微信小程序是否支持删除OSS资源?

微信小程序支持删除OSS资源,但是需要您自行实现签名逻辑。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有