600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 小程序阿里云oss前端直传

小程序阿里云oss前端直传

时间:2021-08-21 00:29:39

相关推荐

小程序阿里云oss前端直传

前言

按照我以前的风格,现在这篇文章也是,在网上找到各个版本的代码,发现无法使用。小程序作为当前最热门的模块,开发bug当然也不在少数,其中上传文件,也不单单依赖于后端。我使用的是阿里云oss,方法是前端直传,首先更正一下,OSS的API并不支持小程序前端直传。

当前各个IT网站交流,贴子的地方,都有很多案例,就不一一贴出来了

一、开发配置

Hbuilder软件的uniapp项目,后端java

二、百度之后一系列开发问题

1、内容冗长不清楚写的什么

各式各样的代码通篇无注释,也不知道写的什么东西(这种人真的不想说。。。估计又是从哪儿扒的)

2、搞清楚前端 “直传”

说是前端直传,要么用的框架,什么element,vant,要么用的组件选的本地文件,然后结果还是把文件路径传给后台而已,其实和本地传文件一点关系都没有。

3、代码运行环境,这个问题就要多说了

百度的时候,各种html,web,或者是vue-element,或者是react。或者是说了,只管传图片的。说真的,到处都是只有图片,没有音频,视屏的方法。

在者杀人猪心,自己封装的另外的代码,不放出来么,就给一个ui界面的div代码。

查了诸多资料,显示,小程序只传,与其他平台不太一样,如果直接授权accessKeyId,和accessKeySecret ,Bukyet并不会成功。

并且oss上传,需要的是一个文件流,而不是feil文件,而流文件需要插件

4、官访文档错误

我在根据oss文档写的时候,发现他们没有提供js插件的下载出处,所以有了bug,无法使用

三、可行方案

1、比较重要的,根据官方文档,直接授权是否可行。

在另一个app项目中,创建oss实例,只需要给出region,accessKeyId,accessKeySecret以及bucket。就可以授权成功,前端直传。

但是小程序并不是这样的,忘记在哪儿看的。意思是,因为小程序没有主体,前端授权密钥风险很大,所以必须设置你的OSS,bucket为公开状态,也是就是其他人也可以进行公共的读写,存储。当然,用户的数据不可能直接暴露。所以pass

所以根据oss文档 微信小程序直传实践 需要STS签名服务,才可以对oss进行直传操作

文档中

步骤1:配置Bucket跨域访问

步骤2:微信小程序配置域名白名单 都没有问题,跟着设置就行,出问题的是 步骤三

为了您的数据安全,建议使用签名方式上传文件。OSS提供以下两种签名方式的代码:

呵呵 ,说白了说就是,不用STS签名我就不建议你用了

————因为我们没有建议不使用STS签名的方法(微笑脸)

2、重头来了

步骤三

分为服务端签名:(使用服务端签名时,您需要先搭建一个签名服务,之后由客户端调用签名服务生成签名。)

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

?????????????????

说白了 还是都需要在后端搭建,那我为什么不选择一个简单的方式?

2、客户端签名

所以我当然选择服务端签名了,前面的通通跳过,要是有后端的别问我,我就一大白,其他的不懂,咱们直接到这一步

首先就是一个大坑

import crypto from ‘crypto-js’;

import { Base64 } from ‘js-base64’;

我就问你这两个文件哪儿来的??????????????!!!!!!

问题不大,直接上链接 npm搜索库/,还好之前有存货

然后复制crypto-jsjs-base64

完美 ,crypto-js 搜索第一个就是,然后搜索js-base64,

问题在这儿 js-base64,这个文件我下载的第一个,名字一摸一样的哪个

但是出错了,源代码:

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}

这里

const policy = Base64.encode(JSON.stringify(policyText)) // policy必须为base64的string

报错告诉我encode is not a function

经过排查,其实是Base64 这个引用根本就找不到,打印{ Base64 },就这里面的东西,找不到。所以后面的 encode就更找不到了

所以我换这个了base-64 ,我用的第一个,原来的包删掉了,然后啥都不换,就可以使用了,这个问题找好久。

3、封装oss请求STS签名的网络请求方法

需要更改的为上面js,代码的这个部分

const credentials = await axios.get('/getToken')

这个网络请求,写自己后台提供的啊。

以防万一,我给你们贴一下我自己写的

// 上传oss获取临时tokenasync getOSSToken({commit,state}) {// 计算签名。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],],};//获取临时信息let data = {token:store.state.token,}let res = await http({url:"account/get_oss_token",data:data})console.log("获取后台OSStoken",res.data.dataMap);const policy = base64.encode(JSON.stringify(policyText)) // policy必须为base64的string。const signature = computeSignature(res.data.dataMap.AccessKeySecret, policy)const formData = {OSSAccessKeyId: res.data.dataMap.AccessKeyId,signature,policy,SecurityToken: res.data.dataMap.SecurityToken,OssFileName:res.data.dataMap.OssFileName}return formData},

至于各个命名是什么意思,文档里面有

三、使用方法

外部,引入,mapActions,然后在methods引入方法,然后直接调用的代码在下面。

async upLoadOSS(newAccount){let that = thislet timestamp = new Date().getTime()console.log('开始上传语音');let res = await that.getOSSToken()const host = "https://*****.oss-cn-######."const signature = res.signature;const ossAccessKeyId = res.OSSAccessKeyIdconst policy = res.policyconst SecurityToken = res.SecurityTokenconst OSSpath = "voice/" + Math.floor(that.uid/10000) + "/" + that.uid + "/" + timestamp + '.mp3'//上面这一步是更具用户的uid是数字几打头的,然后创建的文件夹,方便之后好找,//这个上传,如果目的地没有你写的文件夹,oss会在上传的时候,立马给你现造一个文件夹,方便的很~const key = res.OssFileName +"/" + OSSpath//res.OssFileName,这个是服务器返回的,是测试服,还是正式服的路径地址console.log("___________________________________++++",key)uni.uploadFile({url: host, // 开发者服务器的URL。filePath: that.mine.voiceUrl,name: 'file', // 必须填file。formData: {key,policy,OSSAccessKeyId: ossAccessKeyId,signature,'x-oss-security-token': SecurityToken // 使用STS签名时必传。},success: (res) => {if (res.statusCode === 204) {console.log('上传成功');}else{console.log('请求成功,但是上传失败');}},fail: err => {console.log('请求上传失败');}});},

4、上传回调

uni.uploadFile,用一个参数接收,会有个进度回调。不过这个就不是oss的文档了,是uniapp的问文档。

var uploadTask = uni.uploadFile({url: '/upload', //仅为示例,并非真实接口地址。complete: ()=> {}});uploadTask.abort();

来,各位大哥们,链接直达~ uni.uploadFile(OBJECT)

帮到你的话,点个赞吧d=====( ̄▽ ̄*)b

——Lazy33

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。