uniapp 上传静态资源-- 微信小程序跟QQ小程序上传静态资源到阿里的对象存储 OSS

news/2024/7/19 7:54:50 标签: 小程序, uni-app, 微信小程序

概述

这两天有个需求,要微信小程序跟QQ小程序通过阿里的OSS储存,存放静态资源,遇到了挺多问题,记录一下~~~

文档:此处

服务器签名

其实这个是被误导了,也怪自己没有仔细看文档,不该有这一步,但是做了就记录一下,正好多了解nodejs环境与浏览器环境 API的差别。

服务器直传里面的方法,失败了:浏览器环境没有Buffer 对象
一下是OSS中的DEMO:

BUG1:浏览器环境没有Buffer对象

在这里插入图片描述

只能找方法生成

// 创建一个类似于 Node.js Buffer 的类
class Buffer2 {
    constructor(data) {
        this.data = data;
    }

    // 将string类型转成Buffer数组
    static from(source) {
        if (typeof source === 'string') {
            // 如果源是字符串,则将其编码为指定的编码格式
            const encoder = new TextEncoder();
            let encodedData = encoder.encode(source)
            console.log("encodedData:", encodedData);
            return new Buffer2(encodedData)

            const hexString = Array.from(encodedData).map(byte => byte.toString(16).padStart(2, '0'));
            return new Buffer2(hexString);
        } else {
            throw new Error("不知道什么数据...")
        }
    }


    base64Encode(str) {
        const base64Chars =
            'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
        let result = '';

        for (let i = 0; i < str.length; i += 3) {
            const char1 = str.charCodeAt(i);
            const char2 = str.charCodeAt(i + 1);
            const char3 = str.charCodeAt(i + 2);

            const byte1 = char1 >> 2;
            const byte2 = ((char1 & 3) << 4) | (char2 >> 4);
            const byte3 = ((char2 & 15) << 2) | (char3 >> 6);
            const byte4 = char3 & 63;

            result +=
                base64Chars.charAt(byte1) +
                base64Chars.charAt(byte2) +
                base64Chars.charAt(byte3) +
                base64Chars.charAt(byte4);
        }

        // Handle padding
        const padding = str.length % 3;
        if (padding === 1) {
            result = result.slice(0, -2) + '==';
        } else if (padding === 2) {
            result = result.slice(0, -1) + '=';
        }

        return result;
    }

    toString(encoding = 'base64') {
        if (encoding === 'base64') {
            const binary = [];
            const bytes = new Uint8Array(this.data);

            for (let i = 0; i < bytes.length; i++) {
                binary.push(String.fromCharCode(bytes[i]));
            }

            return this.base64Encode(binary.join(''));
        } else {
            throw new Error('Unsupported encoding');
        }
    }
}


let obj = { a: 1, b: 2 }
let buf = Buffer2.from(JSON.stringify(obj))
console.log("buf:", buf);
console.log(buf.toString("base64"));

用简单的对象obj进行测试~

浏览器环境测试自定义Buffer

在这里插入图片描述

原生node环境使用原生Buffer

在这里插入图片描述
结果一样了~~~

=====

接下来尝试生成DEMO例子中的签名,看看结果一不一样
这里为了数据比对,就将DEMO中的srcT(源代码是实时时间)写死了。
在这里插入图片描述

原生node环境 生成签名

const crypto = require("crypto-js");

class MpUploadOssHelper {
    constructor(options) {
        this.accessKeyId = options.access_key_id;
        this.accessKeySecret = options.access_key_secret;
        // 限制参数的生效时间,单位为小时,默认值为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();
        console.log(srcT);
        srcT = '2023-09-08T06:59:34.489Z'
        const policyText = {
            expiration: srcT,
            conditions: [
                // 限制上传文件大小。
                ["content-length-range", 0, this.maxSize * 1024 * 1024],
            ],
        };
        console.log("policyText:", policyText);
        const buffer = Buffer.from(JSON.stringify(policyText));
        console.log("sss", buffer);
        return buffer.toString("base64");
    }

    signature(policy) {
        return crypto.enc.Base64.stringify(
            crypto.HmacSHA1(policy, this.accessKeySecret)
        );
    }
}

const mpHelper = new MpUploadOssHelper({
    access_key_id: "xxxxxxxxxxxxxxxx",
    access_key_secret: "xxxxxxxxxxxxxxxxxxxxxxxx"
})

// 生成参数。
const params = mpHelper.createUploadParams();
console.log(params);

结果如下:

在这里插入图片描述

微信小程序 生成签名

都是使用一样的代码,只不过小程序用了自定义的class Buffer2

在这里插入图片描述

到这里了,就可以证明基本没问题了~
那试试发送请求有无问题???

肯定有问题啦~~~
参考官网的wx.uploadFile,一系列操作后:
在这里插入图片描述
该错误与下方的客户端签名直传一样~

WAServiceMainContext.js?t=wechat&s=1694156563411&v=3.0.1:1 TypeError: Cannot read property 'sigBytes' of undefined
    at new init (vendor.js? [sm]:43703)
    at Object.HmacSHA1 (vendor.js? [sm]:41454)
    at MpUploadOssHelper.signature (ossHelper.js? [sm]:93)
    at MpUploadOssHelper.createUploadParams (ossHelper.js? [sm]:61)
    at _callee$ (uploadFile2.js? [sm]:45)
    at s (regeneratorRuntime.js:1)
    at Generator.<anonymous> (regeneratorRuntime.js:1)
    at Generator.next (regeneratorRuntime.js:1)
    at asyncGeneratorStep (asyncToGenerator.js:1)
    at c (asyncToGenerator.js:1)(env: Windows,mp,1.06.2308291; lib: 3.0.1)

如下~


客户端签名

参考:此处

BUG1:crypto-js 库 sigBytes

调用 crypto.HmacSHA1 出现 sigBytes

oss uniapp 客户端直传,显示 TypeError: Cannot read property ‘sigBytes’ of undefined

在这里插入图片描述
追溯源头,因为使用了crypto-js

在这里插入图片描述

找到问题了~是自己的问题,给的提示也太那个了,console.log 一下参数。。。
在这里插入图片描述
crypto.HmacSHA1方法中,第二个参数为undefined...


之前实在搞不定,决定去找客服找解决方案,也记录一下,~~~

在这里插入图片描述

微信小程序调用OSS SDK

在vue项目中通过npm i ali-oss,已经可以实现上传,具体可以参考官网DEMO
官网:此处

Bug1:微信API导出的文件只是path

并不是浏览器常用的blob
在这里插入图片描述

Bug2:微信小程序中没有Blob对象

想着自己通过uni.getFileSystemManager() 获取本地文件权限,再转成Blob对象,好家伙,微信开发者工具直接找不到,NND~~~

在这里插入图片描述

后来继续看到了文档,这OSS售后,沃日 T。T …
在这里插入图片描述

总结

大平台,看官方文档就好了,不要相信自己~


http://www.niftyadmin.cn/n/5011421.html

相关文章

实战SpringMVC之CRUD

目录 一、前期准备 1.1 编写页面跳转控制类 二、实现CRUD 2.1 相关依赖 2.2 配置文件 2.3 逆向生成 2.4 后台代码完善 2.4.1 编写切面类 2.4.2 编写工具类 2.4.3 编写biz层 2.4.4 配置mapper.xml 2.4.5 编写相应接口类&#xff08;MusicMapper&#xff09; 2.4.6 处…

【sgLazyCascader】自定义组件:基于el-cascader的懒加载级联菜单,支持异步加载子级菜单

sgLazyCascader源码 <template><div :class"$options.name"><el-cascader :props"props" v-model"model" :placeholder"placeholder || 请选择" :options"options"></el-cascader></div> &l…

day-07 I/O 复用(select)- 多种 I/O 函数 - 多播和广播

一.I/O复用 &#xff08;一&#xff09;基于I/O复用的服务器端 1.多进程服务器 每次服务都需要创建一个进程&#xff0c;需要大量的运算和内存空间 2.复用 只需创建一个进程。 3.复用技术在服务器端的应用 &#xff08;二&#xff09;select函数实现服务器端 &#xff08;…

ETCD集群搭建(实践可用)

概述 etcd 是兼具一致性和高可用性的键值数据库&#xff0c;可以作为保存 Kubernetes 所有集群数据的后台数据库。 - 官方网址&#xff1a; Documentation versions | etcd 准备cfssl证书生成工具 cfssl是一个开源的证书管理工具&#xff0c;使用json文件生成证书. 在任意一…

促进合作交流|旅游专业老师在加拿大访学期间取得初步成果

N老师拟申报CSC&#xff0c;指定国家且要求接收学校不收取板凳费&#xff0c;最终我们分别获得了澳大利亚科廷大学和加拿大圭尔夫大学的邀请函&#xff08;均未收取板凳费&#xff09;。N老师用前者申报了CSC并获批&#xff0c;因签证原因又用后者申请了改派&#xff0c;并在加…

day 52 | 84.柱状图中最大的矩形

84.柱状图中最大的矩形 本题跟接雨水的思路是差不多的&#xff0c;不同的是接雨水找到的凹&#xff0c;这个找的是凸。因此是找到左右第一个比他小的值。因此单调栈中的顺序是从栈头到栈尾单调增。 需要注意的是&#xff0c;为了防止给定的元素是单调增或者单调减&#xff0c;…

Mysten Labs发布关于Sui钱包的漏洞赏金计划

Mysten Labs欢迎安全研究人员和公众参与漏洞赏金计划&#xff0c;为Sui钱包提供反馈&#xff0c;以帮助改善其安全性。 如果您认为自己发现了下文范围内的任何资产中的漏洞、隐私问题、暴露的数据或其他安全问题&#xff0c;希望您能及时向Mysten Labs反馈。以下政策概述了向M…

【浏览器】端数据库存储方案----indexDB、localForage

浏览器存储 localStoragelocalforageIndexDB localStorage 说到本地存储数据&#xff0c;首先想到的是 localStorage&#xff0c;应该很多小伙伴都用过&#xff0c;使用很简单。然而&#xff0c;localStorage 却有下面一些缺点&#xff1a; 存储容量限制&#xff0c;大部分浏…