uniCloud云开发(imgSecCheck踩坑)

1,444 阅读2分钟

前言

小程序云开发还算挺火的,我也去尝试了一下,确实是非常省事,比如以前获取openid,获取小程序码之类的接口都需要通过后端,用小程序云开发的话直接调用api就可以拿到了。 这意味着咱前端也可以独立开发一个完整的小程序了,迈向全栈的一个近道~~

uniCloud你可以理解为跟uni-app配套的云开发。 同样可以发布到多端。 只是坑比较多,我就此来记录一下我的踩坑历程吧

创建项目

  • 本次使用 阿里云 做为云开发服务器(ps:坑点之一)

这个直接看官网

创建云函数

这个我要做的一个功能点是用户上传图片,然后使用canvas编辑绘制后保存到相册

这个其中就要使用到微信自带的图片内容安全识别API

刚开始我的想法是用户在小程序端使用wx.chooseImage拿到图片的路径,然后传给云函数,云函数中直接云调用openapi.security.imgSecCheck就完事了。 想法很美好,可现实是openapi.security.imgSecCheck是小程序中的api,咱用uniCloud可没有这个方法。那怎么办,别怕,遇事不要慌,去uniCloud插件市场找一下有没有对应的插件,一搜还真有,nice。叫做mp-cloud-openapi提供的微信、支付宝等小程序云端能力的封装。

好,我引入后调用报个了undefined错,调试后发现居然没security.imgSecCheck,获取access_token这个倒有。

看来只能云调用方式是行不通了,只能使用https调用

这个就比较常规了,就是用请求方式先拿到access_token,然后在调用安全接口,看代码吧

第一版:

exports.main = async ({imgUrl}, context) => {
	//event为客户端上传的参数
	console.log('event : ', fileID)

	let result = null
   // 获取access_token
	const res = await uniCloud.httpclient.request('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appid&secret=secret', { // 此处appid和seceret要使用自己真实的
		dataType: 'json'
	})

	if(res.status === 200) {
		const { access_token } = res.data
		result = await uniCloud.httpclient.request(`https://api.weixin.qq.com/wxa/img_sec_check?access_token=${access_token}`, {
			method: 'POST',
			dataType: 'json',
			data: {
				media: imgUrl
			},
		})
	}
	//返回数据给客户端
	return result
};

没成功,返回报错信息是media的格式不对,网上查询资料后说要使用buffer格式

然后就想到方法是在小程序端上传图片,然后在云函数中通过Id下载。好我再改造一下

第二版

小程序端

chooseImage() {
    uni.chooseImage({
        count: 1, //默认9
        sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
        sourceType: ['album'], //从相册选择
        success: async (imgRes) => {
            console.log(imgRes.tempFilePaths[0])
            //上传至云存储
            const file = await uniCloud.uploadFile({
                cloudPath: 'userUpload.png',
                filePath: imgRes.tempFilePaths[0]
            })
            console.log(file)
			//把ID传给云函数
            const res = await uniCloud.callFunction({
                name: 'imgSecCheck',
                data: {
                    fileID: file.fileID
                }
            })
            console.log(res)
            this.avatarUrl = imgRes.tempFilePaths[0]
        }
    });
},

云函数

exports.main = async ({fileID}, context) => {
	//event为客户端上传的参数
	console.log('event : ', fileID)

	const file = await uniCloud.downloadFile({fileID })

	let result = null
	const res = await uniCloud.httpclient.request('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appid&secret=secret', { // 此处appid和seceret要使用自己真实的
		dataType: 'json'
	})

	console.log(res.data)
	if(res.status === 200) {
		const { access_token } = res.data
		result = await uniCloud.httpclient.request(`https://api.weixin.qq.com/wxa/img_sec_check?access_token=${access_token}`, {
			method: 'POST',
			dataType: 'json',
			// contentType: 'image/png',
			data: {
				media: file.fileContent
			},
		})
	}
	console.log(result.res)
	console.log(result.data)
	//返回数据给客户端
	return result
};

写好一运行,报了一个错,血崩。。。

然后我又新建了一个腾讯云的项目,把代码拷过去,然后再运行调试,代码是跑通了,但是返回的结果并不正确

关于这个报错,我找了很多文档,看了很多求助的帖子,至今都解决。。。 所以我的问题一直没解决,留个坑,等以后解决了再来填上

总结

  • uniCloud中无法直接使用原生的云调用api,需用到mp-cloud-openapi插件,但是插件功能不是特别全
  • 阿里云不支持在云函数中下载资源
  • 建议还是使用原生的云开发。。。