您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“微信JS-SDK之圖像接口開發(fā)的示例分析”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“微信JS-SDK之圖像接口開發(fā)的示例分析”這篇文章吧。
一、我的思路是:
先調(diào)用“拍照或從手機(jī)相冊(cè)選擇圖片接口”—>選擇成功圖片后—>調(diào)用“上傳圖片接口”—>上傳成功后(也就是圖片上傳到了微信服務(wù)器上)—>調(diào)用“下載圖片接口”—>將圖片下載到自己的服務(wù)器存儲(chǔ)。
二、JSSDK的使用步驟
1、概述
微信JS-SDK是微信公眾平臺(tái)面向網(wǎng)頁(yè)開發(fā)者提供的基于微信內(nèi)的網(wǎng)頁(yè)開發(fā)工具包。
通過(guò)使用微信JS-SDK,網(wǎng)頁(yè)開發(fā)者可借助微信高效地使用拍照、選圖、語(yǔ)音、位置等手機(jī)系統(tǒng)的能力,同時(shí)可以直接使用微信分享、掃一掃、卡券、支付等微信特有的能力,為微信用戶提供更優(yōu)質(zhì)的網(wǎng)頁(yè)體驗(yàn)。
2、使用步驟
步驟一:綁定域名
先登錄微信公眾平臺(tái)進(jìn)入“公眾號(hào)設(shè)置”的“功能設(shè)置”里填寫“JS接口安全域名”。
備注:登錄后可在“開發(fā)者中心”查看對(duì)應(yīng)的接口權(quán)限。
步驟二:引入JS文件
在需要調(diào)用JS接口的頁(yè)面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js
步驟三:通過(guò)config接口注入權(quán)限驗(yàn)證配置
所有需要使用JS-SDK的頁(yè)面必須先注入配置信息,否則將無(wú)法調(diào)用(同一個(gè)url僅需調(diào)用一次,對(duì)于變化url的SPA的web app可在每次url變化時(shí)進(jìn)行調(diào)用)
wx.config({ debug: true, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會(huì)在客戶端alert出來(lái),若要查看傳入的參數(shù),可以在pc端打開,參數(shù)信息會(huì)通過(guò)log打出,僅在pc端時(shí)才會(huì)打印。 appId: '', // 必填,公眾號(hào)的唯一標(biāo)識(shí) timestamp: , // 必填,生成簽名的時(shí)間戳 nonceStr: '', // 必填,生成簽名的隨機(jī)串 signature: '',// 必填,簽名,見(jiàn)附錄1 jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表見(jiàn)附錄2 });
wx.ready(function(){ // config信息驗(yàn)證后會(huì)執(zhí)行ready方法,所有接口調(diào)用都必須在config接口獲得結(jié)果之后,config是一個(gè)客戶端的異步操作,所以如果需要在頁(yè)面加載時(shí)就調(diào)用相關(guān)接口,則須把相關(guān)接口放在ready函數(shù)中調(diào)用來(lái)確保正確執(zhí)行。對(duì)于用戶觸發(fā)時(shí)才調(diào)用的接口,則可以直接調(diào)用,不需要放在ready函數(shù)中。 });
wx.error(function(res){ // config信息驗(yàn)證失敗會(huì)執(zhí)行error函數(shù),如簽名過(guò)期導(dǎo)致驗(yàn)證失敗,具體錯(cuò)誤信息可以打開config的debug模式查看,也可以在返回的res參數(shù)中查看,對(duì)于SPA可以在這里更新簽名。 });
所有接口通過(guò)wx對(duì)象(也可使用jWeixin對(duì)象)來(lái)調(diào)用,參數(shù)是一個(gè)對(duì)象,除了每個(gè)接口本身需要傳的參數(shù)之外,還有以下通用參數(shù):
success:接口調(diào)用成功時(shí)執(zhí)行的回調(diào)函數(shù)。
fail:接口調(diào)用失敗時(shí)執(zhí)行的回調(diào)函數(shù)。
complete:接口調(diào)用完成時(shí)執(zhí)行的回調(diào)函數(shù),無(wú)論成功或失敗都會(huì)執(zhí)行。
cancel:用戶點(diǎn)擊取消時(shí)的回調(diào)函數(shù),僅部分有用戶取消操作的api才會(huì)用到。
trigger: 監(jiān)聽Menu中的按鈕點(diǎn)擊時(shí)觸發(fā)的方法,該方法僅支持Menu中的相關(guān)接口。
備注:不要嘗試在trigger中使用ajax異步請(qǐng)求修改本次分享的內(nèi)容,因?yàn)榭蛻舳朔窒聿僮魇且粋€(gè)同步操作,這時(shí)候使用ajax的回包會(huì)還沒(méi)有返回。
以上幾個(gè)函數(shù)都帶有一個(gè)參數(shù),類型為對(duì)象,其中除了每個(gè)接口本身返回的數(shù)據(jù)之外,還有一個(gè)通用屬性errMsg,其值格式如下:
調(diào)用成功時(shí):"xxx:ok" ,其中xxx為調(diào)用的接口名
用戶取消時(shí):"xxx:cancel",其中xxx為調(diào)用的接口名
調(diào)用失敗時(shí):其值為具體錯(cuò)誤信息
三、開發(fā)及代碼分析詳解(用的是CI框架,只要是MVC模式都可以)
1、先在服務(wù)器端取到:公眾號(hào)的唯一標(biāo)識(shí)appId、生成簽名的時(shí)間戳timestamp、生成簽名的隨機(jī)串nonceStr、簽名signature。
<?php class wx_upload extends xx_Controller { public function __construct() { parent::__construct(); } public function wxUploadImg() { //在模板里引入jssdk的js文件 $this->addResLink('http://res.wx.qq.com/open/js/jweixin-1.0.0.js'); //取得:公眾號(hào)的唯一標(biāo)識(shí)appId、生成簽名的時(shí)間戳timestamp、生成簽名的隨機(jī)串nonceStr、簽名signature這些值,并以json形式傳到模板頁(yè)面 $this->smartyData['wxJsApi'] = json_encode(array('signPackage' => $this->model->weixin->signPackage())); }
圖片上傳控制器
<?php class WxModel extends ModelBase{ public $appId; public $appSecret; public $token; public function __construct() { parent::__construct(); //審核通過(guò)的移動(dòng)應(yīng)用所給的AppID和AppSecret $this->appId = 'wx0000000000000000'; $this->appSecret = '00000000000000000000000000000'; $this->token = '00000000'; } /** * 獲取jssdk所需參數(shù)的所有值 * @return array */ public function signPackage() { $protocol = (!empty($_SERVER['HTTPS'] && $_SERVER['HTTPS'] == 'off' || $_SERVER['port'] == 443)) ? 'https://' : 'http://'; //當(dāng)前網(wǎng)頁(yè)的URL $url = "$protocol$_SERVER['host']$_SERVER['REQUEST_URI']"; //生成簽名的時(shí)間戳 $timestamp = time(); //生成簽名的隨機(jī)串 $nonceStr = $this->createNonceStr(); //獲取公眾號(hào)用于調(diào)用微信JS接口的臨時(shí)票據(jù) $jsApiTicket = $this->getJsApiTicket(); //對(duì)所有待簽名參數(shù)按照字段名的ASCII 碼從小到大排序(字典序)后, //使用URL鍵值對(duì)的格式(即key1=value1&key2=value2…)拼接成字符串$str。 //這里需要注意的是所有參數(shù)名均為小寫字符 $str = "jsapi_ticket=$jsApiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url"; //對(duì)$str進(jìn)行sha1簽名,得到signature: $signature = sha1($str); $signPackage = array( "appId" => $this->AppId, "nonceStr" => $nonceStr, "timestamp" => $timestamp, "url" => $url, "signature" => $signature, "rawString" => $string ); return $signPackage; } /** * 創(chuàng)建簽名的隨機(jī)字符串 * @param int $length 字符串長(zhǎng)度 * @return string 隨機(jī)字符串 */ private function createNonceStr($length == 16) { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $str = ''; for ($i=0; $i < $length; $i++) { $str .= substr(mt_rand(0, strlen($chars)), 1); } return $str; } /** * 獲取公眾號(hào)用于調(diào)用微信JS接口的臨時(shí)票據(jù) * @return string */ private function getJsApiTicket() { //先查看redis里是否存了jsapi_ticket此值,假如有,就直接返回 $jsApiTicket = $this->library->redisCache->get('weixin:ticket'); if (!$jsApiTicket) { //先獲取access_token(公眾號(hào)的全局唯一票據(jù)) $accessToken = $this->getApiToken(); //通過(guò)access_token 采用http GET方式請(qǐng)求獲得jsapi_ticket $result = $this->callApi("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$accessToken&type=jsapi"); //得到了jsapi_ticket $jsApiTicket = $result['ticket']; //將jsapi_ticket緩存到redis里面,下次就不用再請(qǐng)求去取了 $expire = max(1, intval($result['expire']) - 60); $this->library->redisCache->set('weixin:ticket', $jsApiTicket, $expire); } return $jsApiTicket; } /** * 獲取眾號(hào)的全局唯一票據(jù)access_token * @param boolean $forceRefresh 是否強(qiáng)制刷新 * @return string 返回access_token */ private function getApiToken($forceRefresh = false) { //先查看redis是否存了accessToken,如果有了,就不用再去微信server去請(qǐng)求了(提高效率) $accessToken = $this->library->redisCache->get('weixin:accessToken'); //強(qiáng)制刷新accessToken或者accessToken為空時(shí)就去請(qǐng)求accessToken if ($forceRefresh || empty($accessToken)) { //請(qǐng)求得到accessToken $result = $this->callApi("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appId}&secret={$this->appSecret}"); $accessToken = $result['access_token']; $expire = max(1, intval($result['expire']) - 60); //將其存進(jìn)redis里面去 $this->library->redisCache->set('weixin:accessToken', $accessToken, $expire); } return $accessToken; }
獲取到appId、nonceStr、timestamp、signature模型
這里要補(bǔ)充一些 JS-SDK使用權(quán)限簽名算法 的思路和注意點(diǎn)(這里我直接復(fù)制官網(wǎng)文檔給大家看看)
jsapi_ticket
生成簽名之前必須先了解一下jsapi_ticket,jsapi_ticket是公眾號(hào)用于調(diào)用微信JS接口的臨時(shí)票據(jù)。正常情況下,jsapi_ticket的有效期為7200秒,通過(guò)access_token來(lái)獲取。由于獲取jsapi_ticket的api調(diào)用次數(shù)非常有限,頻繁刷新jsapi_ticket會(huì)導(dǎo)致api調(diào)用受限,影響自身業(yè)務(wù),開發(fā)者必須在自己的服務(wù)全局緩存jsapi_ticket 。
1、獲取access_token(有效期7200秒,開發(fā)者必須在自己的服務(wù)全局緩存access_token)
2、用第一步拿到的access_token 采用http GET方式請(qǐng)求獲得jsapi_ticket(有效期7200秒,開發(fā)者必須在自己的服務(wù)全局緩存jsapi_ticket)
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
成功返回如下JSON:
{ "errcode":0, "errmsg":"ok", "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA", "expires_in":7200 }
獲得jsapi_ticket之后,就可以生成JS-SDK權(quán)限驗(yàn)證的簽名了。
簽名算法
簽名生成規(guī)則如下:參與簽名的字段包括noncestr(隨機(jī)字符串), 有效的jsapi_ticket, timestamp(時(shí)間戳), url(當(dāng)前網(wǎng)頁(yè)的URL,不包含#及其后面部分) 。對(duì)所有待簽名參數(shù)按照字段名的ASCII 碼從小到大排序(字典序)后,使用URL鍵值對(duì)的格式(即key1=value1&key2=value2…)拼接成字符串string1。這里需要注意的是所有參數(shù)名均為小寫字符。對(duì)string1作sha1加密,字段名和字段值都采用原始值,不進(jìn)行URL 轉(zhuǎn)義。
即signature=sha1(string1)。 示例:
noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value
步驟1. 對(duì)所有待簽名參數(shù)按照字段名的ASCII 碼從小到大排序(字典序)后,使用URL鍵值對(duì)的格式(即key1=value1&key2=value2…)拼接成字符串string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://www.php.cn/
步驟2. 對(duì)string1進(jìn)行sha1簽名,得到signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
注意事項(xiàng)
1.簽名用的noncestr和timestamp必須與wx.config中的nonceStr和timestamp相同。
2.簽名用的url必須是調(diào)用JS接口頁(yè)面的完整URL。
3.出于安全考慮,開發(fā)者必須在服務(wù)器端實(shí)現(xiàn)簽名的邏輯。
2、取到我們所需要的值后,就在js文件里面開始使用了
uploadImg.tpl
<script> $(function(){ $.util.wxMenuImage('{$wxJsApi|default:""}') }); </script>
uploadImg.js
if(typeof($util)=='undefined')$util={}; $.util.wxMenuImage = function(json) { if (json.length == 0) return; //解析json變成js對(duì)象 wxJsApi = JSON.parse(json); //通過(guò)config接口注入權(quán)限驗(yàn)證配置 wx.config({ debug: false, //開啟調(diào)試模式,調(diào)用的所有api的返回值會(huì)在客戶端alert出來(lái) appId: wxJsApi.signPackage.appId, //公眾號(hào)的唯一標(biāo)識(shí) timestamp: wxJsApi.signPackage.timestamp, //生成簽名的時(shí)間戳 nonceStr: wxJsApi.signPackage.nonceStr, //生成簽名的隨機(jī)串 signature: wxJsApi.signPackage.signature, //簽名 jsApiList: ['chooseImage', 'uploadImage'] //需要使用的JS接口列表 這里我用了選擇圖片和上傳圖片接口 }); //通過(guò)ready接口處理成功驗(yàn)證,config信息驗(yàn)證后會(huì)執(zhí)行ready方法,所有接口調(diào)用都必須在config接口獲得結(jié)果之后 wx.ready(function(){ //得到上傳圖片按鈕 document.querySelector('#uploadImage').onclick = function() { var images = {localId:[],serverId:[]}; //調(diào)用 拍照或從手機(jī)相冊(cè)中選圖接口 wx.chooseImage({ success: function(res) { if (res.localIds.length != 1) { alert('只能上傳一張圖片'); return; } //返回選定照片的本地ID列表 iamges.localId = res.localIds; images.serverId = []; //上傳圖片函數(shù) function upload() { //調(diào)用上傳圖片接口 wx.uploadImage({ localId: images.localId[0], // 需要上傳的圖片的本地ID,由chooseImage接口獲得 isShowProcess: 1, // 默認(rèn)為1,顯示進(jìn)度提示 success: function(res) { //返回圖片的服務(wù)器端ID res.serverId,然后調(diào)用wxImgCallback函數(shù)進(jìn)行下載圖片操作 wxImgCallback(res.serverId); }, fail: function(res) { alert('上傳失敗'); } }); } upload(); } }); } }); } function wxImgCallback(serverId) { //將serverId傳給wx_upload.php的upload方法 var url = 'wx_upload/upload/'+serverId; $.getJSON(url, function(data){ if (data.code == 0) { alert(data.msg); } else if (data.code == 1) { //存儲(chǔ)到服務(wù)器成功后的處理 // } }); } 圖片選擇和圖片上傳接口調(diào)用
圖片選擇和圖片上傳接口調(diào)用
3、圖片上傳完成后會(huì)返回一個(gè)serverId,然后通過(guò)這個(gè)來(lái)下載圖片到本地服務(wù)器
這里先補(bǔ)充下如何調(diào)用下載圖片接口(我直接復(fù)制官方文檔的說(shuō)明了)
公眾號(hào)可調(diào)用本接口來(lái)獲取多媒體文件。請(qǐng)注意,視頻文件不支持下載,調(diào)用該接口需http協(xié)議。
接口調(diào)用請(qǐng)求說(shuō)明
http請(qǐng)求方式: GET http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
參數(shù)說(shuō)明
參數(shù) | 是否必須 | 說(shuō)明 |
---|---|---|
access_token | 是 | 調(diào)用接口憑證 |
media_id | 是 | 媒體文件ID |
返回說(shuō)明
正確情況下的返回HTTP頭如下:
HTTP/1.1 200 OK Connection: close Content-Type: image/jpeg Content-disposition: attachment; filename="MEDIA_ID.jpg" Date: Sun, 06 Jan 2013 10:20:18 GMT Cache-Control: no-cache, must-revalidate Content-Length: 339721 curl -G "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID"
錯(cuò)誤情況下的返回JSON數(shù)據(jù)包示例如下(示例為無(wú)效媒體ID錯(cuò)誤)::
{"errcode":40007,"errmsg":"invalid media_id"} 接下來(lái)看自己寫的代碼 wx_upload.php
/*********************圖片下載到本地服務(wù)器****************************************/ //從微信服務(wù)器讀取圖片,然后下載到本地服務(wù)器 public function upload($media_id) { //圖片文件名 $fileName = md5($this->wxId."/$media_id"); //調(diào)用下載圖片接口,返回路徑 $path = $this->weixin->wxDownImg($media_id, sys_get_temp_dir()."$fileName"); if ($path != false) { //將圖片的路徑插入數(shù)據(jù)庫(kù)去存儲(chǔ) if ($this->model->weixin->updateByWxid($this->wxId, array('img_path'=>$path))) { $this->output->_display(json_encode( array( 'code'=>1, 'msg'=>'上傳成功', 'fileUrl' =>$path; ) )); } else { $this->output->_display(json_encode2(array('code'=>0,'msg' => '上傳失敗','err'=>'1'))); } } else { $this->output->_display(json_encode2(array('code'=>0,'msg' => '上傳失敗','err'=>'2'))); } }
從微信服務(wù)器下載圖片到本地存儲(chǔ)
//從微信服務(wù)器端下載圖片到本地服務(wù)器 public function wxDownImg($media_id, $path) { //調(diào)用 多媒體文件下載接口 $url = "https://cache.yisu.com/upload/information/20201208/260/13216', 'image/gif'=>'.gif', 'image/jpeg'=>'.jpg', 'image/png'=>'.png'); //判斷響應(yīng)首部里的的content-type的值是否是這四種圖片類型 if (isset($types[$info['header']['content_type']])) { //文件的uri $path = $path.$types[$info['header']['content_type']]; } else { return false; } //將資源寫入文件里 if ($this->saveFile($path, $info['body'])) { //將文件保存在本地目錄 $imgPath = rtrim(base_url(), '/').'/img'.date('Ymd').'/'.md5($this->controller->wxId.$media_id).$types[$info['header'['content_type']]]; if (!is_dir($imgPath)) { if(mkdir($imgPath)) { if (false !== rename($path, $imgPath) { return $imgPath; } } } return $path; } return false; } /** * curl請(qǐng)求資源 * @param string $url 請(qǐng)求url * @return array */ private function curl_request($url = '') { if ($url == '') return; $ch = curl_init(); //這里返回響應(yīng)報(bào)文時(shí),只要body的內(nèi)容,其他的都不要 curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_NOBODY, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $package = curl_exec($ch); //獲取curl連接句柄的信息 $httpInfo = curl_getinfo($ch); curl_close($ch); $info = array_merge(array($package), array($httpInfo)); return $info; } /** * 將資源寫入文件 * @param string 資源uri * @param source 資源 * @return boolean */ private function saveFile($path, $fileContent) { $fp = fopen($path, 'w'); if (false !== $localFile) { if (false !== fwrite($fp, $fileContent)) { fclose($fp); return true; } } return false; }
從微信服務(wù)器下載圖片到本地存儲(chǔ)接口
到這里,已經(jīng)完成了:
先調(diào)用“拍照或從手機(jī)相冊(cè)選擇圖片接口”—>選擇成功圖片后—>調(diào)用“上傳圖片接口”—>上傳成功后(也就是圖片上傳到了微信服務(wù)器上)—>調(diào)用“下載圖片接口”—>將圖片下載到自己的服務(wù)器存儲(chǔ)。
這一思路的實(shí)現(xiàn)。我們用到了微信的選擇圖片接口、上傳圖片接口和下載媒體資源接口。
下面我附上這一接口開發(fā)的全部代碼:
<?php class wx_upload extends xx_Controller { public function __construct() { parent::__construct(); } public function wxUploadImg() { //在模板里引入jssdk的js文件 $this->addResLink('http://res.wx.qq.com/open/js/jweixin-1.0.0.js'); //取得:公眾號(hào)的唯一標(biāo)識(shí)appId、生成簽名的時(shí)間戳timestamp、生成簽名的隨機(jī)串nonceStr、簽名signature這些值,并以json形式傳到模板頁(yè)面 $this->smartyData['wxJsApi'] = json_encode(array('signPackage' => $this->model->weixin->signPackage())); } /*********************圖片下載到本地服務(wù)器****************************************/ //從微信服務(wù)器讀取圖片,然后下載到本地服務(wù)器 public function upload($media_id) { //圖片文件名 $fileName = md5($this->wxId."/$media_id"); //調(diào)用下載圖片接口,返回路徑 $path = $this->weixin->wxDownImg($media_id, sys_get_temp_dir()."$fileName"); if ($path != false) { //將圖片的路徑插入數(shù)據(jù)庫(kù)去存儲(chǔ) if ($this->model->weixin->updateByWxid($this->wxId, array('img_path'=>$path))) { $this->output->_display(json_encode( array( 'code'=>1, 'msg'=>'上傳成功', 'fileUrl' =>$path; ) )); } else { $this->output->_display(json_encode2(array('code'=>0,'msg' => '上傳失敗','err'=>'1'))); } } else { $this->output->_display(json_encode2(array('code'=>0,'msg' => '上傳失敗','err'=>'2'))); } } } ?>
<?php class WxModel extends ModelBase{ public $appId; public $appSecret; public $token; public function __construct() { parent::__construct(); //審核通過(guò)的移動(dòng)應(yīng)用所給的AppID和AppSecret $this->appId = 'wx0000000000000000'; $this->appSecret = '00000000000000000000000000000'; $this->token = '00000000'; } /** * 獲取jssdk所需參數(shù)的所有值 * @return array */ public function signPackage() { $protocol = (!empty($_SERVER['HTTPS'] && $_SERVER['HTTPS'] == 'off' || $_SERVER['port'] == 443)) ? 'https://' : 'http://'; //當(dāng)前網(wǎng)頁(yè)的URL $url = "$protocol$_SERVER['host']$_SERVER['REQUEST_URI']"; //生成簽名的時(shí)間戳 $timestamp = time(); //生成簽名的隨機(jī)串 $nonceStr = $this->createNonceStr(); //獲取公眾號(hào)用于調(diào)用微信JS接口的臨時(shí)票據(jù) $jsApiTicket = $this->getJsApiTicket(); //對(duì)所有待簽名參數(shù)按照字段名的ASCII 碼從小到大排序(字典序)后, //使用URL鍵值對(duì)的格式(即key1=value1&key2=value2…)拼接成字符串$str。 //這里需要注意的是所有參數(shù)名均為小寫字符 $str = "jsapi_ticket=$jsApiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url"; //對(duì)$str進(jìn)行sha1簽名,得到signature: $signature = sha1($str); $signPackage = array( "appId" => $this->AppId, "nonceStr" => $nonceStr, "timestamp" => $timestamp, "url" => $url, "signature" => $signature, "rawString" => $string ); return $signPackage; } /** * 創(chuàng)建簽名的隨機(jī)字符串 * @param int $length 字符串長(zhǎng)度 * @return string 隨機(jī)字符串 */ private function createNonceStr($length == 16) { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $str = ''; for ($i=0; $i < $length; $i++) { $str .= substr(mt_rand(0, strlen($chars)), 1); } return $str; } /** * 獲取公眾號(hào)用于調(diào)用微信JS接口的臨時(shí)票據(jù) * @return string */ private function getJsApiTicket() { //先查看redis里是否存了jsapi_ticket此值,假如有,就直接返回 $jsApiTicket = $this->library->redisCache->get('weixin:ticket'); if (!$jsApiTicket) { //先獲取access_token(公眾號(hào)的全局唯一票據(jù)) $accessToken = $this->getApiToken(); //通過(guò)access_token 采用http GET方式請(qǐng)求獲得jsapi_ticket $result = $this->callApi("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$accessToken&type=jsapi"); //得到了jsapi_ticket $jsApiTicket = $result['ticket']; //將jsapi_ticket緩存到redis里面,下次就不用再請(qǐng)求去取了 $expire = max(1, intval($result['expire']) - 60); $this->library->redisCache->set('weixin:ticket', $jsApiTicket, $expire); } return $jsApiTicket; } /** * 獲取眾號(hào)的全局唯一票據(jù)access_token * @param boolean $forceRefresh 是否強(qiáng)制刷新 * @return string 返回access_token */ private function getApiToken($forceRefresh = false) { //先查看redis是否存了accessToken,如果有了,就不用再去微信server去請(qǐng)求了(提高效率) $accessToken = $this->library->redisCache->get('weixin:accessToken'); //強(qiáng)制刷新accessToken或者accessToken為空時(shí)就去請(qǐng)求accessToken if ($forceRefresh || empty($accessToken)) { //請(qǐng)求得到accessToken $result = $this->callApi("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appId}&secret={$this->appSecret}"); $accessToken = $result['access_token']; $expire = max(1, intval($result['expire']) - 60); //將其存進(jìn)redis里面去 $this->library->redisCache->set('weixin:accessToken', $accessToken, $expire); } return $accessToken; } //從微信服務(wù)器端下載圖片到本地服務(wù)器 public function wxDownImg($media_id, $path) { //調(diào)用 多媒體文件下載接口 $url = "https://cache.yisu.com/upload/information/20201208/260/13216', 'image/gif'=>'.gif', 'image/jpeg'=>'.jpg', 'image/png'=>'.png'); //判斷響應(yīng)首部里的的content-type的值是否是這四種圖片類型 if (isset($types[$info['header']['content_type']])) { //文件的uri $path = $path.$types[$info['header']['content_type']]; } else { return false; } //將資源寫入文件里 if ($this->saveFile($path, $info['body'])) { //將文件保存在本地目錄 $imgPath = rtrim(base_url(), '/').'/img'.date('Ymd').'/'.md5($this->controller->wxId.$media_id).$types[$info['header'['content_type']]]; if (!is_dir($imgPath)) { if(mkdir($imgPath)) { if (false !== rename($path, $imgPath) { return $imgPath; } } } return $path; } return false; } /** * curl請(qǐng)求資源 * @param string $url 請(qǐng)求url * @return array */ private function curl_request($url = '') { if ($url == '') return; $ch = curl_init(); //這里返回響應(yīng)報(bào)文時(shí),只要body的內(nèi)容,其他的都不要 curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_NOBODY, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $package = curl_exec($ch); //獲取curl連接句柄的信息 $httpInfo = curl_getinfo($ch); curl_close($ch); $info = array_merge(array($package), array($httpInfo)); return $info; } /** * 將資源寫入文件 * @param string 資源uri * @param source 資源 * @return boolean */ private function saveFile($path, $fileContent) { $fp = fopen($path, 'w'); if (false !== $localFile) { if (false !== fwrite($fp, $fileContent)) { fclose($fp); return true; } } return false; } } ?>
<html> <head> </head> <body> <button id="uploadImage">點(diǎn)擊上傳圖片</button> <script> $(function(){ $.util.wxMenuImage('{$wxJsApi|default:""}') }); </script> </body> </html>
if(typeof($util)=='undefined')$util={}; $.util.wxMenuImage = function(json) { if (json.length == 0) return; //解析json變成js對(duì)象 wxJsApi = JSON.parse(json); //通過(guò)config接口注入權(quán)限驗(yàn)證配置 wx.config({ debug: false, //開啟調(diào)試模式,調(diào)用的所有api的返回值會(huì)在客戶端alert出來(lái) appId: wxJsApi.signPackage.appId, //公眾號(hào)的唯一標(biāo)識(shí) timestamp: wxJsApi.signPackage.timestamp, //生成簽名的時(shí)間戳 nonceStr: wxJsApi.signPackage.nonceStr, //生成簽名的隨機(jī)串 signature: wxJsApi.signPackage.signature, //簽名 jsApiList: ['chooseImage', 'uploadImage'] //需要使用的JS接口列表 這里我用了選擇圖片和上傳圖片接口 }); //通過(guò)ready接口處理成功驗(yàn)證,config信息驗(yàn)證后會(huì)執(zhí)行ready方法,所有接口調(diào)用都必須在config接口獲得結(jié)果之后 wx.ready(function(){ //得到上傳圖片按鈕 document.querySelector('#uploadImage').onclick = function() { var images = {localId:[],serverId:[]}; //調(diào)用 拍照或從手機(jī)相冊(cè)中選圖接口 wx.chooseImage({ success: function(res) { if (res.localIds.length != 1) { alert('只能上傳一張圖片'); return; } //返回選定照片的本地ID列表 iamges.localId = res.localIds; images.serverId = []; //上傳圖片函數(shù) function upload() { //調(diào)用上傳圖片接口 wx.uploadImage({ localId: images.localId[0], // 需要上傳的圖片的本地ID,由chooseImage接口獲得 isShowProcess: 1, // 默認(rèn)為1,顯示進(jìn)度提示 success: function(res) { //返回圖片的服務(wù)器端ID res.serverId,然后調(diào)用wxImgCallback函數(shù)進(jìn)行下載圖片操作 wxImgCallback(res.serverId); }, fail: function(res) { alert('上傳失敗'); } }); } upload(); } }); } }); } function wxImgCallback(serverId) { //將serverId傳給wx_upload.php的upload方法 var url = 'wx_upload/upload/'+serverId; $.getJSON(url, function(data){ if (data.code == 0) { alert(data.msg); } else if (data.code == 1) { //存儲(chǔ)到服務(wù)器成功后的處理 // } }); }
以上是“微信JS-SDK之圖像接口開發(fā)的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。