微信H5页面调起相册和摄像头,实现图片上传,并上传到本地服务器

本文详细介绍了微信JS-SDK的config权限配置流程,包括如何获取并设置appId、timestamp、nonceStr和signature等参数。同时,深入探讨了图片上传至微信服务器的实现方法,以及从微信服务器下载图片至本地服务器的步骤。此外,还提供了通过本地接口在页面上显示图片的技巧,并展示了如何将图片信息提交至本地服务器。

1、config权限配置

$.ajax({
    url:'wx_getConfig',            
    type:'get',
    dataType:'json',
    async:false,
    success:function(data){
        var appId = data[0].appId;
        var timestamp = data[0].timestamp;
        var nonceStr = data[0].nonceStr;
        var signature = data[0].signature;
        wx.config({  
            debug: false,//调试模式   当为tru时,开启调试模式 
            appId: appId,  
            timestamp: timestamp.toString(),//签名时间戳
            nonceStr: nonceStr, //生成签名的随机串 
            signature: signature,//签名                    
            jsApiList: ['chooseImage','uploadImage','getLocalImgData','downloadImage'],
            success:function(){
                alert("配置成功")
            },
            fail:function(){
                alert("配置失败")
            }
        });  
    },
    error:function(){
        alert("error");
    }
})

2、config配置成功

   当config配置成功后,就会执行ready函数,所有的操作必须等到config配置完成后才会执行,如果是页面加载就执行的操作,就必须放在ready中执行。如果是在被触发时执行的操作,则不需要放在ready中

wx.ready(function () {
    // 在这里调用 API
    wx.checkJsApi({
      jsApiList: [
        'chooseImage',
        'uploadImage',
        'getLocalImgData',
        'downloadImage'
      ],
      success: function (res) {
        console.log(JSON.stringify(res));
      }
    });
});

3、调取摄像头和相册

function takePicture(nums) {  
   wx.chooseImage({  
       count: 1,  
       needResult: 1,  
       sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有  
       sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有  
       success: function (data) {                  
           localIds = data.localIds[0];   // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片                           
           var num1 = nums;
           wxuploadImage(localIds,num1);
           wxgetLocalImgData(localIds,num1);
       },  
       fail: function (res) {            
           alterShowMessage("操作提示", JSON.stringify(res), "1", "确定", "", "", "");  
           }    
       });  
   }  

4、上传到微信服务器

function wxuploadImage(e,num) {
    var $hiddenImg= $(".hiddenImg");
    wx.uploadImage({  
        localId: e, // 需要上传的图片的本地ID,由chooseImage接口获得  
        isShowProgressTips: 1, // 默认为1,显示进度提示  
        success: function (res) {                                        
            mediaId = res.serverId;                    
            wxdownloadImage(mediaId)
            $($hiddenImg[num]).val(mediaId);          
        },  
        fail: function (error) {  
            picPath = '';  
            localIds = '';  
            alert(Json.stringify(error));          
        }          
    });  
}  

此时的图片上传,是将图片上传到微信服务器,我们可以根据获取到的medisId 将图片下载到本地服务器。

5、获取本地图片接口,在本地显示

function wxgetLocalImgData(e,num){
    var $myimg = $(".myimg");    
    if(window.__wxjs_is_wkwebview){
     wx.getLocalImgData({
         localId: e, // 图片的localID
         success: function (res) {                    
              var localData = res.localData; // localData是图片的base64数据,可以用img标签显示
              localData = localData.replace('jgp', 'jpeg');//iOS 系统里面得到的数据,类型为 image/jgp,因此需要替换一下                                            
              $($myimg[num]).attr("src", localData);
         },fail:function(res){
          alert("显示失败");
         }
     });
    }else{
        $($myimg[num]).attr("src", e);
        
    }
}

此接口仅在 iOS WKWebview 下提供,用于兼容 iOS WKWebview 不支持 localId 直接显示图片的问题

6、提交到本地服务器,实现本地上传

function tijiao(){
    var userInfo = JSON.parse(localStorage.getItem("UserInfoKey"));
    var user = JSON.parse(localStorage.getItem("user"));
    var userId = user.userId;
    var company = userInfo.mainInfo;
    var kfCompanyProvince = userInfo.kfCompanyProvince;
    var kfCompanyCity = userInfo.kfCompanyCity;
    var kfCompanyDistrict = userInfo.kfCompanyDistrict;
    var companyAddress = userInfo.detailAddress;
    var userType = user.userType;
    var userName = userInfo.contacts;
    var principalPhoneCode = userInfo.phone;
    var img1 = $($(".hiddenImg")[0]).val();
    var img3 = $($(".hiddenImg")[1]).val();
    var img5 = $($(".hiddenImg")[2]).val();
    var img6 = $($(".hiddenImg")[3]).val();
    var img7 = $($(".hiddenImg")[4]).val();    
     $.ajax({
            url:'user_uploadInformation',
            data:{
                  "userId":userId,
                  "company":company,
                  "kfCompanyProvince":kfCompanyProvince,
                  "kfCompanyCity":kfCompanyCity,
                  "kfCompanyDistrict":kfCompanyDistrict,
                  "companyAddress":companyAddress,
                  "userType":userType,
                  "userName":userName,
                  "principalPhoneCode":principalPhoneCode,
                  "img1":img1,
                  "img3":img3,
                  "img5":img5,
                  "img6":img6,
                  "img7":img7
            },
            type:'post',
            dataType:'json',
            async:false,
            success:function(data){
                if(data.code == 0){
                    mui.alert("认证失败,请重新认证")
                }else if(data.code == 1){
                    mui.alert("申请提交成功,请稍后",function(){
                        window.location.href="../../index/carManLookImg.jsp"
                    })
                    
                }
            },
            error:function(data){
                alert("上传失败")
            }
        })        
}
<think>由于需要适配小程序H5,我们需要使用uniapp的多端兼容特性。uniapp提供了统一的API来调用相机,但在不同平台(小程序H5)上,底层实现不同,但我们可以使用相同的API。 步骤: 1. 使用`uni.chooseImage`方法调用相机或选择图片,这个API在H5小程序上都可以使用。 2. 获取到图片的临时路径后,将图片显示在页面上。 3. 将图片上传服务器,使用`uni.uploadFile`方法。 注意:在H5端,`uni.chooseImage`调用的实际上是浏览器的文件选择,所以需要区分是直接拍照还是从相册选择。但根据需求,我们需要调用相机,所以可以设置`sourceType: ['camera']`,这样在H5上会尝试调用摄像头(注意:H5上调用摄像头需要https协议,且部分浏览器支持)。在小程序上,设置`sourceType: ['camera']`会直接调用相机。 另外,在H5端,由于浏览器的安全限制,无法直接获取到文件的真实路径,所以返回的是Blob URL,这个URL可以直接用于展示,但上传时需要转换为FormData上传。 但是,`uni.uploadFile`在H5端会自动处理,我们只需要传入临时路径即可。 下面是一个示例代码: 页面结构(template): ```html <template> <view> <button @click="takePhoto">拍照</button> <image v-if="imageSrc" :src="imageSrc" mode="aspectFit"></image> <button v-if="imageSrc" @click="upload">上传</button> </view> </template> ``` 脚本部分(script): ```javascript <script> export default { data() { return { imageSrc: '', // 用于展示的图片路径 tempFile: null // 临时文件路径,用于上传 } }, methods: { takePhoto() { // 调用相机 uni.chooseImage({ count: 1, // 默认1 sourceType: ['camera'], // 使用相机 success: (res) => { // 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片 this.imageSrc = res.tempFilePaths[0]; this.tempFile = res.tempFiles[0]; // 注意:在H5端,tempFiles[0]是一个File对象,而tempFilePaths[0]是Blob URL。在小程序端,tempFiles[0]是一个对象,包含path(同tempFilePaths[0])size等。 }, fail: (err) => { console.error(err); } }); }, upload() { if (!this.imageSrc) { uni.showToast({ title: '请先拍照', icon: 'none' }); return; } // 上传文件 // 注意:在H5端,uni.uploadFile会自动将本地路径转换为File对象,然后上传。在小程序端,直接使用临时路径上传。 uni.uploadFile({ url: 'https://example.com/upload', // 替换为你的上传接口 filePath: this.imageSrc, name: 'file', // 后端接收的文件参数名 formData: { // 可以附加额外的表单数据 'user': 'test' }, success: (uploadRes) => { // 上传成功,uploadRes.data是服务器返回的数据,可能是字符串,需要根据实际情况解析 console.log(uploadRes.data); uni.showToast({ title: '上传成功', icon: 'success' }); }, fail: (err) => { console.error(err); uni.showToast({ title: '上传失败', icon: 'none' }); } }); } } } </script> ``` 解释: 1. 在`takePhoto`方法中,我们调用`uni.chooseImage`,指定`sourceType`为`['camera']`,这样就会调用相机。 2. 成功回调中,`res.tempFilePaths`是一个数组,我们取第一个作为图片的临时路径,赋值给`imageSrc`用于页面展示。同时,我们也保存`res.tempFiles[0]`,但实际上在上传时我们只需要`tempFilePaths[0]`(即`this.imageSrc`)。 3. 在`upload`方法中,我们使用`uni.uploadFile`上传文件。其中`filePath`参数就是临时文件路径(即`this.imageSrc`)。在H5端,这个路径是Blob URL,`uni.uploadFile`内部会将其转换为File对象上传。在小程序端,直接上传临时路径对应的文件。 注意:在H5端,使用相机拍照后,返回的临时路径是一个Blob URL(如:blob:http://...),这个URL在页面刷新或者离开后就会失效,所以建议在上传完成后,如果需要持久化展示,需要将图片上传服务器然后使用服务器返回的URL。 另外,在H5端调用摄像头,需要确保你的网站是https的,否则浏览器可能会阻止调用摄像头。 相关问题: 1. 如何在小程序H5实现相册选择图片上传? 2. 在H5端,如何兼容用户没有摄像头的情况? 3. 如何在上传图片时显示上传进度? 4. 如何压缩图片后再上传?</think>以下是一个使用 UniApp 实现适配小程序 H5 的相机拍照、展示上传的完整解决方案: ```html <template> <view class="container"> <!-- 拍照按钮 --> <button @click="takePhoto">拍照</button> <!-- 图片预览 --> <image v-if="imageSrc" :src="imageSrc" mode="aspectFit" class="preview-image"></image> <!-- 上传按钮 --> <button v-if="imageSrc" @click="uploadImage" :loading="uploading">上传图片</button> <!-- 进度条 --> <progress v-if="uploading" :percent="progress" show-info stroke-width="3" /> </view> </template> <script> export default { data() { return { imageSrc: '', // 图片临时路径 uploading: false, // 上传状态 progress: 0, // 上传进度 tempFile: null // 临时文件对象 } }, methods: { // 拍照方法 async takePhoto() { try { // 调用相机 const res = await uni.chooseImage({ count: 1, sourceType: ['camera'], // 使用相机 sizeType: ['compressed'], // 压缩图片 camera: 'back' // 使用后置摄像头 }) if (res.tempFilePaths.length > 0) { this.imageSrc = res.tempFilePaths[0] this.tempFile = res.tempFiles[0] } } catch (error) { console.error('拍照失败:', error) uni.showToast({ title: '拍照失败', icon: 'none' }) } }, // 上传图片 async uploadImage() { if (!this.imageSrc) return this.uploading = true this.progress = 0 try { // 上传文件 const uploadRes = await uni.uploadFile({ url: 'https://your-api-endpoint.com/upload', // 替换为你的上传接口 filePath: this.imageSrc, name: 'file', // 后端接收的文件字段名 formData: { userId: '123', // 附加的表单数据 type: 'avatar' }, header: { 'Authorization': 'Bearer your-token' // 认证信息 }, // 进度监听 progress: (res) => { this.progress = res.progress } }) // 处理上传结果 if (uploadRes.statusCode === 200) { const data = JSON.parse(uploadRes.data) uni.showToast({ title: '上传成功', icon: 'success' }) console.log('服务器返回:', data) } else { throw new Error(`上传失败: ${uploadRes.statusCode}`) } } catch (error) { console.error('上传错误:', error) uni.showToast({ title: '上传失败', icon: 'none' }) } finally { this.uploading = false } } } } </script> <style scoped> .container { padding: 20px; display: flex; flex-direction: column; align-items: center; } button { width: 80%; margin: 15px 0; } .preview-image { width: 100%; height: 300px; margin: 20px 0; border: 1px solid #eee; border-radius: 5px; } progress { width: 80%; margin-top: 10px; } </style> ``` ### 代码解释: 1. **多端适配核心**: - 使用 `uni.chooseImage` API 调用相机,该 API 在微信小程序 H5 上行为一致 - 在 H5 环境会自动调用浏览器摄像头 - 在小程序环境调用微信原生相机 2. **拍照流程**: - `takePhoto` 方法调用相机获取临时文件路径 - `sourceType: ['camera']` 指定使用相机而非相册 - `sizeType: ['compressed']` 启用图片压缩 3. **图片展示**: - 使用 `<image>` 组件显示拍摄的图片 - `mode="aspectFit"` 确保图片按比例完整显示 4. **上传功能**: - `uploadFile` API 处理多端文件上传 - `progress` 回调实现上传进度显示 - 支持附加表单数据认证头信息 5. **错误处理**: - 使用 try-catch 捕获拍照上传错误 - 通过 `uni.showToast` 显示友好提示 ### 注意事项: 1. **H5 环境特殊要求**: - 必须使用 HTTPS 协议 - 需要用户授权摄像头权限 - 部分浏览器可能需要手动启用摄像头 2. **小程序配置**: - 需要在 `manifest.json` 添加相机权限: ```json "mp-weixin": { "appid": "your-appid", "permission": { "scope.camera": { "desc": "需要摄像头权限" } } } ``` 3. **文件上传限制**: - 小程序单文件最大 10MB - H5 无明确限制但受服务器配置影响 4. **临时路径有效期**: - 小程序:退出当前页面后失效 - H5页面刷新后失效 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值