最近做一款集体小程序,波及到图片的上传,公布时没通过,大抵意思是说须要做微信内容平安检测,校验一张图片是否含有守法违规内容,看了微信凋谢文档,
的确一头雾水,也百度搜寻了一些大佬的做法,貌似都有报错,搞了老久老久了,实际上总结进去就是传输的格局不对上面我就来说说正确的做法与步骤(我本人我的项目外面的局部代码,大伙看个思维就行了):
总的来说:因为内容平安接口时不容许间接在前端调用的,有平安问题,所以前端将图片转为 base64 格局传到后端,后端再由 base64 转化为 buffer,在后端调用内容平安接口就 ok 了
步骤 1.(前端)
从相册中抉择一张图片 uni.chooseImage---》获取到图片门路 tempFilePaths[0],重要的看 imgSecCheck 办法
chooseImage(sourceType) {
const _this = this;
uni.chooseImage({
count: 1, // 默认 9
sizeType: ['original', 'compressed'], // 能够指定是原图还是压缩图,默认二者都有
sourceType,
success: function(chooseRes) {
try {_this.handleImg(chooseRes.tempFilePaths[0]).then((res) => {if (res.code !== 200) {
uni.showModal({
content: res.message || '出错了',
showCancel: false
})
}
uni.hideLoading()})
} catch (e) {uni.hideLoading()
console.error(e)
}
// finally{// uni.hideLoading()
// }
}
});
},
async handleImg(localPath) {
const _this = this;
uni.showLoading({
title: '图片解决中...',
mask: true
})
const checkRes = await this.imgSecCheck(localPath)
console.log('checkRes', checkRes)
if (checkRes.code !== 200) {
this.segmentResTempUrl = null
return checkRes
}
}
步骤 2.(前端)
先解释一下我为什么要先将图片转化为 base64,因为其它方法都已失败告终哈哈
// 校验图片是否含有守法违规内容
async imgSecCheck(localPath) {const base64Res = await this.getImgBase64(localPath)
if (base64Res.code !== 200) {return base64Res}
// c 这里的 request 是对 uniCloud.callFunction 的一个简略的封装, 上面有介绍
return await this.$request({
name: 'file',
dataType: 'json',
data: {
action: 'imgSecCheck',
params: {source: base64Res.result}
},
})
},
async getImgBase64(localPath) {console.log('localPath', localPath)
return new Promise((resolve, reject) => {uni.getFileSystemManager().readFile({
filePath: localPath,
encoding: 'base64',
success: res => {
let datas = res.data
// console.log('datas', datas)
// const base64 = uni.arrayBufferToBase64(datas)
resolve({
code: 200,
result: datas
})
},
fail: (e) => {console.error('getImgBase64 fail', e)
reject({message: 'base64 转换出错'})
}
})
})
},
request.js 封装
const request = async(funcParams) => {const {name,data}=funcParams;
const {action,params}=data;
return new Promise((resolve, reject) => {
uniCloud.callFunction({
name,
data,
success(response) {console.log(`callFunction(${name}/${action}) response:`, response.result);
switch (response.result.code) {
case 200:
break;
case 10002: // 登录 token 过期
break;
case 10001: // 用户未受权
break;
default:
break;
}
resolve(response.result);
},
fail(err) {console.error(`callFunction(${name}/${action}) error:`, err);
reject({message:'申请出错'});
}
})
});
}
export default request
到此前端局部就讲完了,写得有些啰嗦,实际上只须要看 imgSecCheck 这个办法就行了
步骤 3(后端)先看看必要参数
所以还要获取微信 access_token
async function getAccessToken() {
let result = null
const res = await uniCloud.httpclient.request(
'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxa954bf263f23a7a6&secret=f025543f4dda4a7809cb42d27b279f35', { // 此处 appid 和 seceret 要应用本人实在的
dataType: 'json'
})
if (res.status === 200) {
const {access_token} = res.data
result = {
code: 200,
message: '获取 getAccessToken 胜利',
result: access_token
}
} else {
result = {
code: 500,
message: '获取 getAccessToken 失败',
}
}
return result
}
async function imgSecCheck(params) {
const {result} = await getAccessToken()
if (result) {const {status,data} = await uniCloud.httpclient.request(`https://api.weixin.qq.com/wxa/img_sec_check?access_token=${result}`, { // 此处 appid 和 seceret 要应用本人实在的
dataType: 'json',
files: [Buffer.from(params.source, 'base64')]
})
if(status===200&&data.errcode===0){
return {
code:200,
message:'图片非法'
}
}else{
return {
code:500,
message:'图片出错或违规'
}
}
}
}
exports.main = async (event) => {let params = event.params || {}
let payload = {}
let res = {}
switch (event.action) {
case 'imgSecCheck':
res = await imgSecCheck(params);
break;
default:
res = {
code: 403,
message: '非法拜访'
}
break;
}
// 返回数据给客户端
return res
};
至此完结撒花
此性能我整合在了一个本人写的小程序外面,有趣味的能够微信搜寻(toopian)或者扫描小程序码体验一下(就是那个抠图的性能,大家能够体验一下)