uni.chooseImage失效
环境
:uni-app开发H5项目,H5项目链接webview嵌入app中
原因
:webview中不支持,需要由APP进行原生支持
方案
:由APP原生支持返回base64编码,处理base64编码后进行OSS上传实现拍照/选照上传功能
1.相关方法
// oss.js
import crypto from 'crypto-js';
import { Base64 } from 'js-base64'; // 计算签名
// 生成签名
function computeSignature(accessKeySecret, canonicalString) {
return crypto.enc.Base64.stringify(crypto.HmacSHA1(canonicalString, accessKeySecret));
}
// 构造OSS相关参数
export function getFormDataParams({ accesskeyid, accesskeysecret, securitytoken }) {
if (accesskeyid && accesskeysecret && securitytoken) {
const date = new Date();
date.setHours(date.getHours() + 1);
const policyText = {
expiration: date.toISOString(),
// 设置policy过期时间。
conditions: [
// 限制上传大小。
['content-length-range', 0, 1024 * 1024 * 1024]
]
};
const policy = Base64.encode(JSON.stringify(policyText)); // policy必须为base64的string。
const signature = computeSignature(accesskeysecret, policy);
const host= 'https://display-image.oss-cn-hangzhou.aliyuncs.com/'
const formData = {
OSSAccessKeyId: accesskeyid,
signature,
policy,
'x-oss-security-token': securitytoken,
host
};
return formData;
}
return null;
}
// base64编码转文件
export function base64ToFile(base64, filename) {
if (!base64) {
return null
}
const arr = base64.split(',')
if (!arr.length || !arr[0]) {
return null
}
// .match(/:(.*?);/)[1]
const mimeMatcher = (arr[0]).match(/:(.*?);/)
if (!mimeMatcher) {
return null
}
const mime = mimeMatcher[1]
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
}
// 获取文件名
export function getExtName(filePath) {
return filePath.slice(filePath.lastIndexOf('.'))
}
2.触发拍照/选照
async uploadCoverImage(evt) {
// #ifdef H5
this.setData({
callback: async(resp) => {
// resp为处理后返回数据,设置回调可用于处理上传成功后的文件
}
})
this.onShowPhoto(evt)
// #endif
},
onShowPhoto(evt) {
this.setData({
photoShow: true, // 控制动作列表显隐
photoEvent: evt
})
},
onSelectPhoto(event) {
let type = "1"
if(event.detail.name == '拍摄') type = "0"
this.getImage(type)
},
3.利用原生APP支持的API获取图片的base64编码
getImage(type) {
let _this = this
let config = {
// API对应参数
}
window.xtion.getPhoto(config, function(res, error){
if(error != null) {
uni.showToast({
title: '无法上传',
icon: 'error'
});
}
// 获取图片数据
if(res.length === 0) {
uni.showToast({
title: '未选择照片',
icon: 'error'
});
}
else {
_this.uploadImage(res[0])
}
})
},
4.处理base64编码返回图片
uploadImage(evt, cb) {
// #ifdef H5
uni.showLoading({
title: '上传中...'
});
this.handleSelectFilesChange({
file: base64ToFile(evt.file, getExtName(evt.filePath)),
base64: evt.file
})
// #endif
}
handleSelectFilesChange(e) {
const selectedFile = e.file
const base64 = e.base64
if (!selectedFile) return
this.uploadFile(selectedFile)
.then((res) => {
this.callback(res) // 上传成功触发回调的后续处理
})
.catch(error => {
this.callback({
status: 'fail',
filePath: base64, // 图片base64编码
imgUrl: '' // 图片远程路径
})
})
},
5.OSS上传图片
// 获取OSS上传相关参数
async getUploadConfig() {
const resp = await getOssParams();
console.log('upload params:', resp);
if (resp?.resp_data) {
const config = getFormDataParams(resp?.resp_data);
if (config) {
this.setData({
uploadConfig: config
});
}
}
},
async uploadFile(file) {
const uid = guid()
const dateTime = new Date()
const url = uid
const tenantCode = uni.getStorageSync('tenantcode') || '1101190'
const objectKey = `${url.substr(0, 3)}/img/${dateTime.getFullYear()}${dateTime.getMonth() + 1}${dateTime.getDate()}/${tenantCode}/${url}.jpg`
const config = this.uploadConfig
// 构建上传formData
let formData = new FormData()
formData.append('key',objectKey)
formData.append("policy",config.policy)
formData.append("OSSAccessKeyId",config.OSSAccessKeyId)
formData.append('x-oss-security-token',config['x-oss-security-token'])
formData.append("signature",config.signature)
formData.append("file",file)
// 开始上传
try {
let res = await http({
method:'post',
url: config.host,
headers: { 'Content-Type': 'multipart/form-data' },
data:formData
})
console.log('成功提交:', res)
const imgUrl = `${config.host}${objectKey}`;
return {
status: 'success',
filePath: imgUrl,
imgUrl,
file
}
} catch (e) {
console.log('error: ', e)
throw Error(e)
}
},
版权声明:本文为qq_44242707原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。