赞
踩
第一次写CSDN,有什么写的不清楚的地方大家指点。
我本是做前端的,干了6年左右,前一阵接了个私活,做微信小程序。技术上小程序用的原生+vant,后台管理系统用的Vue+Element,本来是前后端分离按照正常流程去做,结果后端拉胯走了(He Tui~),最后因为前期用户量并不多,决定用小程序云开发先挺过这段时间。
虽然小程序干了不老少,后端只会Python,但是我也是第一次用云开发写后端逻辑和操作数据库,不太熟悉,感觉会遇到很多坑,这就遇到了上传这个大坑。
功能需求:小程序端是一般的表单提交+上传最多三张图片,后台管理系统也有上传,要求通过云开发中部署静态网站,调用云函数完成所有数据交互。
碎碎念:接活之前已经用测试账号做过技术验证,也没什么问题,但是心里总有一种不安,感觉上传这块要遇大坑,想什么来什么。
由于是第一次做,肯定前期会看很多相应的文章或者逛逛社区,总的来讲网上的文章目前可以分为三类:
方法1,从想法到放弃
上边也说了,我们完全没有后端,而且也确实需要web调用云函数,并且我希望所有数据库操作和上传等均在云函数中进行。所以在web端只用SDK调callFunction方法去做数据交互,再加上权限等问题果断放弃方法1。有老大就要说了,那就用先用wx.cloud.uploadFile解决小程序后边再说嘛,反正早晚也得解决,不如直接解决了算了(我不,强迫症,爱咋咋地)。
方法2,从验证成功到莫名报错到放弃
对于没有干过的技术方案怎么能不认真验证可行性呢,坑了甲方咋办!(主要是怕扣我钱,我的小钱钱~),咳咳,言归正传。
总的思路是这样的:(前期云开发准备工作跳过,自己搜去)
(1)首先通过wx.chooseImage选择图片
- chooseImages(){
- let _this = this
- wx.chooseImage({
- count: 3,
- sizeType: ['original', 'compressed'],
- sourceType: ['album', 'camera'],
- success(res){
- const tempFilePaths = res.tempFilePaths
- _this.setData({
- images: tempFilePaths
- })
- }
- })
- }
(2)使用 wx.getFileSystemManager().readFile()将图片转成base64字符串,然后callFunction传过去,如果多张上传就循环。
- getImageBase64(){
- wx.getFileSystemManager().readFile({
- filePath: images,
- encoding: 'base64',
- success(response){
- wx.cloud.callFunction({
- name: 'quickstartFunctions',
- config: {
- env: '******'
- },
- data: {
- type: 'uploadPicture',
- path: 'images/test.png',
- file: response.data
- },
- success(res) {
- console.log(res)
- }
- })
- }
- })
- }
(3)在云函数中接到base64然后转回来上传
- const cloud = require('wx-server-sdk');
-
- cloud.init({
- env: cloud.DYNAMIC_CURRENT_ENV
- });
-
- exports.main = async (event, context) => {
- try {
- return await cloud.uploadFile({
- cloudPath: event.path,
- fileContent: Buffer.from(event.file, 'base64')
- })
- } catch (e) {
- return e;
- }
- }
神奇的来了,技术验证顺风顺水,在实际开发中,CV大法过来改了改,结果报!错!了!连云函数都没进去。报了-404006
面向百度变成的我,百了各种度,都没找到原因,但是只要不传base64就能进云函数,明明验证的代码还在那摆着,可他依旧报错坚挺,而且至今都不知道为啥(有知道的告诉告诉孩子吧,孩子不容易啊)
既然找不到原因那就果断放弃吧,毕竟世上无难事,只要肯放弃,我转向了方法3
方法3,从瞎蒙到抓狂到成功
官方对wx.cloud.CDN的定义是这样的↓↓↓↓↓↓↓↓↓↓↓↓
示例代码更是简单的不能再简单
OK,我们能从这上边得出什么呢?当然啥都看不出来,TX技术文档某些部分的模糊程度大家都懂的,反正我看的云里雾里的。简单来说呢,wx.cloud.CDN需要放在wx.cloud.callFunction中用,就是用来传大文件的,它会在云函数中对应字段返回一个地址,通过地址拿到你传的数据,但是怎么拿,他!没!说!(Tui~)
下面看我的代码,由于昨天弄了一天,虽然也是按照CDN方式弄的,但是图片无法查看。今天莫名其妙的调试成功了,还没来得及整理代码(凑合看吧)
获取图片的步骤跟上边一样,可是为什么不用现成的代码块可以复制粘贴呢,因为我不想让你们粘,主要看imageUpload中的代码,最后我会解释为啥我上边刚说的wx.cloud.callFunction用,这就出幺蛾子了。
解释一下,一共三个参数,file,path,suffix。file是CDN地址,把chooseImage获取的图片临时文件地址放入CDN中,返回个地址当做参数传到云函数中,path是云储存的地址,我只传了一个文件夹地址,剩下的交给云函数生成,suffix是文件后缀,我也不知道传的png还是jpg,而且保证上传的复用性,所以获取了个后缀一起传过去了,就这么简单。
重点来了,怎么获取CDN地址中的数据嘞~有请axios,熟悉不,就是Vue中的axios,请求一下子不就好了。抄家伙!在云函数中安装依赖npm install axios --save,先安上,要不准报错undefined。
也有人用got,我也用过了,不知道是不是版本原因不能用require引入,云函数又不能import,放弃。经过我的不懈努力!OK看代码
- const cloud = require('wx-server-sdk')
- const PARAMS = require('../params.json') // 配置JSON
- const SendData = require('../sendData/index') // 发送数据回来的函数,加了code和是否成功
- const axios = require('axios') // 引入axios
-
- cloud.init({
- env: PARAMS.env
- })
-
- exports.main = async (event, context) => {
- try {
- // cloud.uploadFile可以接arraybuffer,所以获取类型设置为arraybuffer
- let imgBuffer = await axios({
- method:'get',
- url:event.data.file,
- responseType: 'arraybuffer',
- headers: { "Content-Type": "*" },
- })
- // 上传
- const cloudId = await cloud.uploadFile({
- cloudPath: event.data.path+'U'+Date.now()+event.data.suffix,
- fileContent: Buffer.from(imgBuffer.data)
- })
- // 成功后返回云储存的fileID
- return SendData(cloudId.fileID)
- } catch (e) {
- return SendData('图片上传失败', 200, false)
- }
- }
看看储存里,这就上传成功了。
函数SendData中return的就是个JSON不用纠结我怎么写的,我只是懒。
刚才上边说CDN只能放在callFunction中使用,但是我放在了imageUpload中,心机之蛙一直摸你肚子!这就是我自己封装的,咳咳。我可不想每次都得写wx.callFunction巴拉巴拉,呸,代码太多了!
其实本质就是callFunction,简单介绍一下我的做法,我将callFunction封装成了一个函数Call,把请求的云函数名和数据等进行操作整理,还有自定义loading文字,然后把Call暴露出来,建立api文件夹,引入Call,把所有的交互函数当做api一样进行统一管理。如果大家有兴趣我抽空可以把代码扔出来大家喷喷。
如果大家觉得有帮助,做后台管理系统接口的时候再发一期怎么在vue项目中使用云函数,并且部署,我去整理代码,继续搬砖了,散会
碎碎念:也不一定会有第二期,毕竟我懒
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。