项目中,微信利用jweixin进行图片上传

来源:互联网 发布:腾讯强力卸载软件 编辑:程序博客网 时间:2024/06/05 05:00
首先,需求是这样的,要在微信端直接调用相册或者是照相机,如果是照相机的话那就利用file里边的capture="camera"属性即可。如果是要直接定位到相册,那么就得用app里边调用硬件里边的相册了。
还好有微信的接口可以用。
微信为开发者提供了一套非常完备的接口:

上图是微信开发js-sdk文档中的部分接口,其中就有专门的图像接口,而且功能十分完备有拍照、从相册选择图片,预览图片,上传图片,下载图片的接口。
实现微信接口上传的第一步便是要获得接口权限。
1.  接口权限获得方法
步骤一:绑定域名
先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。如果你使用了支付类接口,请确保支付目录在该安全域名下,否则将无法完成支付。
备注:登录后可在“开发者中心”查看对应的接口权限。
步骤二:引入JS文件
 
在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js
请注意,如果你的页面启用了https,务必引入https://res.wx.qq.com/open/js/jweixin-1.0.0.js,否则将无法在iOS9.0以上系统中成功使用JSSDK
如需使用摇一摇周边功能,请引入 jweixin-1.1.0.js
备注:支持使用AMD/CMD 标准模块加载方法加载
步骤三:通过config接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息
wx.config({
    debug: true, //开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', //必填,公众号的唯一标识
    timestamp: , //必填,生成签名的时间戳
    nonceStr: '',//必填,生成签名的随机串
    signature:'',//必填,签名,见附录1
    jsApiList: []//必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
      其中最重要的一步就是签名生成。签名生成步骤:使用AppID和AppSecret调用本接口来获取access_token,然后用拿到的access_token采用http GET方式请求获得jsapi_ticket
成功返回如下JSON:
{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA",
"expires_in":7200
}
     获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
     签名生成算法:
       (签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。)
        步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1
        步骤2.string1进行sha1签名,得到signature
2.调用接口实现上传功能
  当第一步中config接口注入权限验证配置完成后便能使用微信提供的接口来实现上传功能了。
[javascript] view plain copy
  1. wx.ready(function(){  
  2.   
  3.   // 在这里面调用微信接口  
  4.  debug: false,  
  5.     appId: '',  
  6.     timestamp:’’,  
  7.     nonceStr: '',  
  8.     signature: '',  
  9.     jsApiList: [  
  10.            //这里是所要调用的接口名称,因为要实现上传,所以调用图像的四个接口  
  11.           'chooseImage',  
  12.           'previewImage',  
  13.           'uploadImage',  
  14.           'downloadImage',   
  15.      ]  
  16.   //在这里写具体调用接口的函数  
  17. ;  


完成了这步,我们的图片已经上传到微信的服务器上了,接下来我们要做的是将图片从微信服务器上下载到自己的服务器上。
3.下载上传到微信服务器上的图片到自己服务器
    每张图片上传到微信服务器上会自动返回用户一个media_id,用户可以根据所返回media_id来下载图片到自己的服务器上 方法为:
   
[php] view plain copy
  1. $url = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=";.$token."&media_id=".$media_id."";  
  2. function http_get_data($url) {    
  3.         
  4.     $ch = curl_init ();    
  5.     curl_setopt ( $ch, CURLOPT_CUSTOMREQUEST, 'GET' );    
  6.     curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false );    
  7.     curl_setopt ( $ch, CURLOPT_URL, $url );    
  8.     ob_start ();    
  9.     curl_exec ( $ch );    
  10.     $return_content = ob_get_contents ();    
  11.     ob_end_clean ();    
  12.         
  13.     $return_code = curl_getinfo ( $ch, CURLINFO_HTTP_CODE );    
  14.     return $return_content;    
  15. }   
  16. $return_content = http_get_data($url);    
$return_content中就是图片,然后通过file_put_contents($file_url,$return_content)将图片放到你想要的地方
这样就完成了图片的上传
 四个接口的使用方法:
       拍照或从手机相册中选图接口
[javascript] view plain copy
  1.         wx.chooseImage({  
  2. count: 1, // 默认9  
  3. sizeType: ['original''compressed'], // 可以指定是原图还是压缩图,默认二者都有  
  4. sourceType: ['album''camera'], // 可以指定来源是相册还是相机,默认二者都有  
  5. success: function (res) {  
  6.     var localIds = res.localIds; // 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片  
  7. }  


预览图片接口
[javascript] view plain copy
  1. wx.previewImage({  
  2.     current: ''// 当前显示图片的http链接  
  3.     urls: [] // 需要预览的图片http链接列表  
  4. });  


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


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

踩的坑:微信的jweixin的js文件已经到了1.2.0版本,否则加载1.0.0版本的话,wx的getLocalImgData方法就没有,那么就不能够生成一个base64的图片。
wx.getLocalImgData({ localId: '', // 图片的localID success: function (res) { var localData = res.localData; // localData是图片的base64数据,可以用img标签显示 } });

上面代码的localId是从选择图片接口返回的参数得来的:

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

这里有一个隐藏的bug,就是安卓拿到的localData不是base64编码的字符串。虽然微信接口文档里面说明了此接口仅在 iOS WKWebview 下提供(具体内容可去查看微信jssdk说明文档
但是难免会遇到将选择上传的图片编码然后再提交到后台的需求。一般的做法都是将图片上传到文件服务器,而不是将图片编码然后一起提交。这种方式存在很多不科学性,但我们这里忽略这个不科学性。
真要这样做时,这里ios和android兼容性就会出现问题。
ios拿到的localData是图片有误的base64编码data:image/jpg;base64,而安卓拿到的localData不仅没有前缀data:image/jpg;base64, 而且拿到的结果也不是base64编码的字符串!!!
这里并不能通过canvas去将获取到的图片编码,因为拿到的路径不是本地图片的路径。
解决办法如下:
安卓对返回的localData再做一次base64编码,再加上编码头部data:image/jpg;base64

注意:
微信头像的接口不能够上传的时候就压缩,而chooseImage方法里头的sizeType: ['original', 'compressed'],是表示上传的时候是不是选择原图,而不是表示上传了图之后再压缩。因为微信没有提供这个判断图片大小的接口。

原创粉丝点击