小程序直传OBS
本文最后更新于 458 天前,其中的信息可能已经有所发展或是发生改变。

注意事项

  • 计算签名时依赖引用“crypto-js”及“js-base64”两个开源组件,因此需要在微信小程序项目中设置使用NPM模块。
  • 在微信小程序中进行编译时,如果在引入“crypto-js”包时出现“Maximum call stack size exceed”报错,请升级微信小程序开发客户端至最新版本。
  • 上传过程中返回405时,请检查指定的endpoint是否为对应上传桶的桶域名。

操作步骤

  1. 设置桶的跨域访问权限。微信小程序基于BrowerJS进行开发,受同源安全策略的要求,不同域间的网站脚本和内容如需交互,需要配置跨域资源共享(CORS)规范。华为云对象存储服务OBS支持CORS规范,允许跨域访问OBS中的资源,具体配置步骤请参见配置跨域资源共享。CORS规则配置项建议:

小程序直传OBS_对象存储服务 OBS_最佳实践_华为云 (huaweicloud.com)

使用芋头直接上传文件到华为OBS,可以使用@vivo-miniprogram/ Huawei – OBS -sdk包。此包提供了一个简单的API,用于上传文件到华为OBS。

首先,使用npm安装包:

npm install @vivo-miniprogram/huawei-obs-sdk

然后,在您的Taro代码中导入包,并使用uploadFile方法将您的文件上传到华为OBS。例子:

import { uploadFile } from '@vivo-miniprogram/huawei-obs-sdk';

// Replace these values with your own
const accessKeyId = 'your-access-key-id';
const secretAccessKey = 'your-secret-access-key';
const bucketName = 'your-bucket-name';
const objectName = 'your-object-name';
const filePath = 'path/to/your/file';

// Upload the file to Huawei OBS
uploadFile({
  accessKeyId,
  secretAccessKey,
  bucketName,
  objectName,
  filePath,
}).then(() => {
  console.log('File uploaded successfully');
}).catch((error) => {
  console.error('Error uploading file:', error);
});

请确保将accessKeyId、secretAccessKey、bucketName、objectName和filePath值替换为您自己的值。您可以在华为OBS控制台中找到您的接入密钥ID和秘密接入密钥。

参考

wx.uploadFile({
  url: 'https://your-obs-server',
  filePath: 'path/to/local/file',
  name: 'file',
  formData: {
    key: 'path/to/file',
    policy: 'your-policy',
    signature: 'your-signature',
  },
  success: (res) => {
    console.log('Upload success:', res);
  },
  fail: (err) => {
    console.error('Upload error:', err);
  },
});
实际案例要传的参数比较多
Configuration.js

// 指定OBS服务相关信息:AK,SK,EndPoint
class Configuration{

  constructor(){

    this.AccessKeyId = '' //AK

    this.SecretKey = ''  //SK

    this.SecurityToken = ''  // securitytoken

    this.EndPoint = ''  // 访问路径 小程序 调用 前缀 要加 桶名

    this.bucket = ''   //桶名

    this.Expiration = ''  // token 有效期

    this.FileUploadPath = ''  // 上传到 云上的 文件夹地址

    this.DomainUrl = ''  //图片访问路径



  }

  setConfig({ accessKeyId,secretKey,securityToken,bucket,endpoint, expiresAt, fileUploadPath,domainUrl}){


    this.AccessKeyId = accessKeyId

    this.SecretKey = secretKey

    this.SecurityToken = securityToken

    this.bucket = bucket

    const _endpoint = `https://${bucket}.${endpoint}`

    this.EndPoint = _endpoint

    this.Expiration = expiresAt

    this.FileUploadPath = fileUploadPath

    this.DomainUrl = domainUrl


  }

}


module.exports = new Configuration();

主要代码

const config = require('./Configuration.js');
const getPolicyEncode = require('./getPolicy.js');
const getSignature = require('./GetSignature.js');
const uuid = require('./uuid')

const setObsConfig = params => {

  config.setConfig(params)

}

const OBSupload = function (filePath,fileName){

  if(!filePath){
    wx.showToast({
      title: '文件路径不能为空',
      icon: 'none',
    });
    return false
  }


 return wxUpload(filePath,fileName)

}



const wxUpload = (filePath,fileName)=>{

  const pathSplit =  filePath.split('.')

  const photoType = pathSplit[pathSplit.length-1]

  const contentType = `image/${photoType}`


  let _fileName = fileName ? fileName : `picture-mini`

  //重名会被覆盖,这里加下 时间戳
  _fileName = `${_fileName}-${uuid()}.${photoType}`

     //设定policy内容
  const OBSPolicy = {
    "expiration": config.Expiration, //token有效期
    "conditions": [
      {"bucket": config.bucket},        //Bucket name
      {'content-type':contentType},
      {"x-obs-acl": "public-read"},
      { 'key': `${config.FileUploadPath}${_fileName}`},
    ]
  }

  const policyEncoded = getPolicyEncode(OBSPolicy);                    //计算policy编码值
  const signature = getSignature(policyEncoded, config.SecretKey);     //计算signature

  return new Promise((revose,reject)=>{

    wx.uploadFile({
      url: config.EndPoint,
      filePath: filePath,
      name: 'file',
      header: {
        'content-type': 'multipart/form-data; boundary=-9431149156168',
      },
      formData: {
        'AccessKeyID': config.AccessKeyId,
        'policy': policyEncoded,
        'signature': signature,
        // "x-obs-security-token": config.SecurityToken,
        'content-type':contentType,
        'x-obs-acl': 'public-read',
        'key': `${config.FileUploadPath}${_fileName}`,
      },
      success: function(res){

        if(res.statusCode=='204'){
          // http图片地址 如:"https://img/20210630/picture-mini-1625018844736.png"

          const domainUrl = config.DomainUrl
          const _chart = domainUrl.endsWith('/') ?  '' : '/'
          const url = `${config.DomainUrl}${_chart}${config.FileUploadPath}${_fileName}`
          //相对路径 如:'/dev/zj-mall/img/20210624/321321-1624539083010.png'
          const path = `${config.FileUploadPath}${_fileName}`

          revose({
            url ,
            path,
            domainUrl,
          })
        }
        else{
          reject(res)
        }
      },
      fail: function(e){
        reject(e)
      }
    })


  })

}




module.exports = {

  OBSupload,

  setObsConfig


}

上传代码

import Taro from '@tarojs/taro'
import OBSWx from '@/lib/OBS'
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'

dayjs.extend(utc)

const config = {
  AccessKeyId: '',
  SecretKey: '',
  EndPoint: '',
  Bucket: '',
}

const prefixPath = 'upload/mp/'

export default async function obsUploadFile(filePath: string) {
  // const { filePath } = options

  if (!filePath) {
    Taro.showToast({
      title: '无效目录',
      icon: 'error',
    })
    throw new Error('Invalid filePath')
  }

  OBSWx.setObsConfig({
    accessKeyId: config.AccessKeyId,
    secretKey: config.SecretKey,
    // 桶名
    bucket: config.Bucket,
    // 访问路径 小程序 调用 前缀 要加 桶名  返回拼装好的 如 :`https://${bucket}.${endpoint}`
    endpoint: config.EndPoint,
    //  token 有效期
    expiresAt: dayjs
      .utc()
      .add(30, 'm')
      .format(),
    fileUploadPath: prefixPath, // 上传到 云上的 文件夹地址
    domainUrl: `https://${config.Bucket}.${config.EndPoint}/`, // 图片访问路径
  })

  const result = await OBSWx.OBSupload(filePath)

  return result
}

评论

  1. 杨江河
    2年前
    2023-4-10 14:53:12

    大佬为啥我这里导入包的时候说找不到资源呢?能咨询一下你吗?457425537我q

    • 博主
      杨江河
      2年前
      2023-4-25 19:31:22

      你是怎么上传的

  2. ddd
    2年前
    2023-4-12 21:54:57

    无法使用

本文评论已关闭
上一篇
下一篇