赞
踩
环境:uni-app开发H5项目,H5项目链接webview嵌入app中
原因:webview中不支持,需要由APP进行原生支持
方案:由APP原生支持返回base64编码,处理base64编码后进行OSS上传实现拍照/选照上传功能
// 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('.')) }
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) },
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]) } }) },
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: '' // 图片远程路径 }) }) },
// 获取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) } },
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。