完美解决微信网页部分机型无法上传图片的问题(最直接有效的方法)

4,059 阅读4分钟

前言

前几天在公司的项目里发现的问题,本来是没有什么问题的,偏偏在客户的的机型上就上传不了,纠结这个bug纠结了一天(秉承需求至上,总不能跟客户说,这个做不了,是你的机型不支持),所以特地开一篇短文,做为总结。


寻找问题

百度了一下    微信网页上传图片失败

发现部分机型上传图片失败是微信网页的历史遗留问题,一直没有得到解决,很多人在官方社区里提问,官方的答复更多的也只是针对机型去解决,并没有给出很好的方案(或许是我没有找到)。

而且这个问题还是相当多的


百度里的各种方法

第一种 :插件方式  (使用两个不同的jq上传文件插件)

www.cnblogs.com/cai-rd/p/39… (博客园)

看不下去,可性性不高,本来用个插件不复杂,作者写得复杂难看,耗时高,还是使用我下文的方法更快


第二种.  <input type="file" accept="image/png,image/jpeg,image/gif,image/jpg">

      改成

  <input type="file" accept="image/">

      可行性不高,但是想要尝试的不阻拦


第三种. 也就是我现在的方法,使用微信网页的JS-SDK,网上有大佬推荐使用,但是没用明确的方法演示,所以我专门写一章记录一下


4.还有用flash去做的(我也是醉了,我做个上传图片还要去学falsh?)....



正文

使用微信网页的JS-sdk里的api去上传文件

1.在页面头部引入JS-sdk

 <script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>

2. 通过config接口注入权限验证配置

wx.config({
  debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  appId: '', // 必填,公众号的唯一标识
  timestamp: , // 必填,生成签名的时间戳
  nonceStr: '', // 必填,生成签名的随机串
  signature: '',// 必填,签名
   jsApiList: [                'chooseImage',                'getLocalImgData',                'uploadImage',    ]// 必填,需要使用的JS接口名列表
});

(有这个问题一般都是在现有项目上发现的问题,开发微信网页这个总不能没用吧)


3 .调用接口(里面修改需要插入到页面的元素,就可以直接复制使用了)

 //直接打开!拍照或从手机相册选择图片的接口 
    wx.chooseImage({
      count: 1,
      sizeType: ['original', 'compressed'],
      sourceType: ['album', 'camera'], 
      success: function (res) {
           // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
           //临时图片
           var localId = res.localIds[0]; 
         // console.log(localId);
          --------------------------------- 
           wx.getLocalImgData({ 
           localId: localId,
            success: function (res) {
                  // (注意)需要把获取的base64渲染在页面div元素
                   var result1 = document.getElementById("list2");
                  //localData是图片的base64,我们在这一步用base64做图片 
                    var localData = res.localData;
                   //做if判断是因为 wx.getLocalImgData要兼容android和IOS
                   //IOS
                  if (browser.versions.ios) {
                        //渲染图片到页面 
                      result1.innerHTML = '<img src="' + localData + '"  alt=""/>' 
                    } else {
                       //android 
                        //渲染图片到页面 
                       localData = ' data:image/png;base64,' + localData;
                       result1.innerHTML = '<img src="' + localData + '" alt=""/>' 
                    }                        
              }                    
          });                                    
        }            
});  

(机型系统判断我会放在文章末尾)

4.上传到后端

需要使用到的有两个api

1. 前端使用 wx.uploadImage 上传到微信服务器并返回服务器id

wx.uploadImage({
  localId: '', // 需要上传的图片的本地ID,由chooseImage接口获得
  isShowProgressTips: 1, // 默认为1,显示进度提示
  success: function (res) {
    var serverId = res.serverId; // 返回图片的服务器端ID
  }
});


2.  后端使用 wx.downloadImage 用前端返回服务的id去微信服务器获取id

wx.downloadImage({
  serverId: '', // 需要下载的图片的服务器端ID,由uploadImage接口获得
  isShowProgressTips: 1, // 默认为1,显示进度提示
  success: function (res) {
    var localId = res.localId; // 返回图片下载后的本地ID
  }
})

这里就不做过多演示了

微信官方文档   

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html


5.HTML

在html上有很大不同

以往我们做一个美观的上传按钮是这样的


难免有些繁杂


现在我们可以是

 <div class="up_load_img" onclick="up_load_img"></div>

通过这个假定的 up_load_img 事件去包含第三步的代码就可以选择图片并预览了,也可以去上传了

(写过小程序的应该都知道这挺像小程序的api的,自我感觉这样的api挺好)

6.判断设备版本(直接复制粘贴)

 var browser = {  
          versions: function () {
                var u = navigator.userAgent, app = navigator.appVersion;
                return {
         //移动终端浏览器版本信息
                    trident: u.indexOf('Trident') > -1, //IE内核
                    presto: u.indexOf('Presto') > -1, //opera内核
                    webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
                    gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐内核
                    mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否为移动终端
                    ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
                    android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android终端或uc浏览器
                    iPhone: u.indexOf('iPhone') > -1, //是否为iPhone或者QQHD浏览器
                    iPad: u.indexOf('iPad') > -1, //是否iPad
                    webApp: u.indexOf('Safari') == -1 //是否web应该程序,没有头部与底部
                };
            }(),
            language: (navigator.browserLanguage || navigator.language).toLowerCase()
        }

最后一句 wx浏览器的X5内核是真得多坑,大家平时开发还是得多多注意


end~

有问题请联系作者

看完确定不点个赞再走?