Nodejs獲取微信簽名并使用JSSDK

Nodejs獲取微信簽名并使用JSSDK

1、測試號申請
2、獲取access_token
3、獲取 jsapi_ticket
4、獲取簽名算法
5、JSSD使用

上一篇我們講了基本的準備工作,接下來,進入實戰,由于樓主我并沒有備案過的域名(窮,沒錢,沒辦法哈),還好, 一直通不過簽名驗證,微信比較人性化,提供測試號,可以測大部分的接口,并且設置JS接口安全域名,沒有限制,可以寫任何地址,哪怕是localhost:9999也是可以的。

1、接口測試號申請

由于用戶體驗和安全性方面的考慮,微信公眾號的注冊有一定門檻,某些高級接口的權限需要微信認證后才可以獲取。

所以,為了幫助開發者快速了解和上手微信公眾號開發,熟悉各個接口的調用,微信推出了微信公眾帳號測試號,通過手機微信掃描二維碼即可獲得測試號,在這個測試號里面可以模擬各種操作,比如分享啥的,很容易通過驗證。

微信JSSDK開發文檔

進入微信公眾帳號測試號申請系統

image

體驗接口權限表

類目 功能 接口 每日調用上限/次 操作
對話服務 基礎支持 獲取access_token 2000
獲取微信服務器IP地址 無上限
接收消息 驗證消息真實性 無上限
接收普通消息 無上限
接收事件推送 無上限
接收語音識別結果 無上限 [關閉](javascript:void(0);)
發送消息 自動回復 無上限
客服接口 500000
群發接口 詳情
模板消息(業務通知) 100000
用戶管理 用戶分組管理 詳情
設置用戶備注名 10000
獲取用戶基本信息 500000
獲取用戶列表 500
獲取用戶地理位置 無上限 [關閉](javascript:void(0);)
推廣支持 生成帶參數二維碼 100000
長鏈接轉短鏈接接口 1000
界面豐富 自定義菜單 詳情
素材管理 素材管理接口 詳情
功能服務 智能接口 語義理解接口 1000
設備功能 設備功能接口 無上限 設置 [關閉](javascript:void(0);)
多客服 獲取客服聊天記錄 5000
客服管理 詳情
會話控制 詳情
網頁服務 網頁帳號 網頁授權獲取用戶基本信息 無上限 [修改](javascript:void(0);)
基礎接口 判斷當前客戶端版本是否支持指定JS接口 無上限
分享接口 獲取“分享到朋友圈”按鈕點擊狀態及自定義分享內容接口 無上限
獲取“分享給朋友”按鈕點擊狀態及自定義分享內容接口 無上限
獲取“分享到QQ”按鈕點擊狀態及自定義分享內容接口 無上限
獲取“分享到騰訊微博”按鈕點擊狀態及自定義分享內容接口 無上限
圖像接口 拍照或從手機相冊中選圖接口 無上限
預覽圖片接口 無上限
上傳圖片接口 無上限
下載圖片接口 無上限
音頻接口 開始錄音接口 無上限
停止錄音接口 無上限
播放語音接口 無上限
暫停播放接口 無上限
停止播放接口 無上限
上傳語音接口 無上限
下載語音接口 無上限
智能接口 識別音頻并返回識別結果接口 無上限
設備信息 獲取網絡狀態接口 無上限
地理位置 使用微信內置地圖查看位置接口 無上限
獲取地理位置接口 無上限
界面操作 隱藏右上角菜單接口 無上限
顯示右上角菜單接口 無上限
關閉當前網頁窗口接口 無上限
批量隱藏功能按鈕接口 無上限
批量顯示功能按鈕接口 無上限
隱藏所有非基礎按鈕接口 無上限
顯示所有功能按鈕接口 無上限

2、獲取 access_token 訪問令牌

access_token(有效期7200秒,開發者必須在自己的服務全局緩存access_token`)

https請求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

參數說明

參數 是否必須 說明
grant_type 獲取access_token填寫client_credential
appid 第三方用戶唯一憑證
secret 第三方用戶唯一憑證密鑰,即appsecret

返回說明

正常情況下,微信會返回下述JSON數據包給公眾號:

{"access_token":"ACCESS_TOKEN","expires_in":7200}

實戰項目代碼:

獲取 access_token

config/index.json:

image

api/accessToken.js

// 獲取 access_token
const config = require('../config/index.json'); // 配置數據
const axios = require('axios'); // 請求api
const CircularJSON = require('circular-json');

// (設置 | 獲取)緩存方法
const cache = require('../utils/cache');

module.exports = getAccessToken = (res) => {

  const fetchUrl = `${config.getAccessToken}?grant_type=client_credential&appid=${config.appid}&secret=${config.appsecret}`;
  // console.log(fetchUrl, config);

  // 獲取緩存
  cache.getCache('access_token', function (cacheValue) {
    // 緩存存在
    if (cacheValue) {
      const result = CircularJSON.stringify({
        access_token: cacheValue,
        from: 'cache'
      });
      res.send(result);
    } else {
      // 調取微信api
      axios.get(fetchUrl).then(response => {
        let json = CircularJSON.stringify(response.data);
                res.send(json);
        // 設置緩存
        if (response.data.access_token) {
          cache.setCache('access_token', response.data.access_token)
        }
      }).catch(err => {
        console.log('axios occurs ', err);
      });
    }
  });

};

這里用的 axios請求微信api,獲取 access_token;

由于access_token 只有7200秒有效時間,并且限制一天最多調2000 次,所以中控服務器最好作緩存,這里使用的 node-cache,做了access_token的緩存,并且刪除的緩存的時間也設置的是 7200s,這樣在 access_token失效的時候,node緩存也會被刪除。

utils/cache.js

// node-cache 保存和獲取緩存

const NodeCache = require("node-cache");
const myCache = new NodeCache({
  stdTTL: 7200, // 緩存過期時間
  checkperiod: 120 // 定期檢查時間
});


// 設置緩存
var setCache = function (key, value) {
  // 設置緩存
  myCache.set(key, value, function (err, success) {
    if (!err && success) {
      console.log(key + "保存成功", value);
    }
  });
};

// 獲取緩存
var getCache = function (key, callback) {
  // 讀取緩存
  myCache.get(key, function (err, value) {
    if (!err) {
      if (value) {
        console.log(`存在于緩存中${key}=${value}`);
        callback(value);
      } else {
        console.log(`${key} not found in node-cache`);
        callback();
      }
    } else {
      console.log('get ' + key + ' cache occurs error =', err);
    }
  });
};



module.exports = {
  setCache,
  getCache
}

node-cache只能存活于當前進程里面,如果當前node命令被重啟,將會重新去請求微信服務器,所以不太適合。

這里其實最好存在 redis數據庫里,

路由設置:

app.js

const express = require('express');
const api = require('./api');
const path = require('path');
const app = express();

// accessToken 獲取token
app.get('/getAccessToken', (req, res) => {
  api.accessToken(res);
});

....

結果:

image

這是第一次請求,access_token從微信服務器獲取最初的數據。

接下來是第二次請求,access_token將會緩存中讀取。

image

3、獲取 jsapi_ticket臨時票據

生成簽名之前必須先了解一下jsapi_ticketjsapi_ticket是公眾號用于調用微信JS接口臨時票據。正常情況下,jsapi_ticket的有效期為7200秒,通過access_token來獲取。由于獲取jsapi_ticket的api調用次數非常有限,頻繁刷新jsapi_ticket會導致api調用受限,影響自身業務,開發者必須在自己的服務全局緩存jsapi_ticket

用上一步拿到的access_token采用http GET方式請求獲得jsapi_ticket(有效期7200秒,開發者必須在自己的服務全局緩存jsapi_ticket):<https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi>

成功返回如下JSON:

{
"errcode":0,
"errmsg":"ok",
"ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd841ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUWvsdshFKA",
"expires_in":7200
}

獲得jsapi_ticket之后,就可以生成JS-SDK權限驗證的簽名了。

回到之前說的那個Nodejs + Express項目中:

api/jsapiTicket.js

// 通過 access_token 獲取 jsapi_ticket 臨時票據
const axios = require('axios'); // 請求api
const CircularJSON = require('circular-json');
const config = require('../config/index.json');
const cache = require('../utils/cache');


module.exports = get_jsapi_ticket = (access_token, res) => {

  const fetchUrl = config.getJsapiTicket + access_token;
  console.log('>>>>', fetchUrl)
  // 判斷是否存在于緩存中
  const cacheName = "jsapi_ticket";
  cache.getCache(cacheName, function (cacheValue) {
    if (cacheValue) {
      const result = CircularJSON.stringify({
        ticket: cacheValue,
        from: 'cache'
      });
      res.send(result);
    } else {
      // 調取微信api
      axios.get(fetchUrl).then(response => {
        let json = CircularJSON.stringify(response.data);
        // promise
        res.send(json);
        // 設置緩存
        if (response.data.ticket) {
          cache.setCache(cacheName, response.data.ticket)
        }
      }).catch(err => {
        // console.log('axios occurs ', err);
      });
    }
  });

}

路由設置:

const express = require('express');
const api = require('./api');
const path = require('path');
const app = express();
//express請求別的路由中間件
require('run-middleware')(app);

// 獲取 jsapi_ticket 臨時票據
app.get('/getTicket', (req, res) => {
  app.runMiddleware('/getAccessToken', function (code, body, headers) {
    const result = JSON.parse(body);
    console.log('User token:', result.access_token);
    api.jsapiTicket(result.access_token, res);
  })
});

....

這里比較特殊的地方,是用 run-middleware 這個 npm package,從一個路由去直接請求另外一個路由的數據。

這樣避免重復很多邏輯。我們直接請求路由獲取上一步的 access_token;

廢話不多說,運行一下:

第一次,是從微信服務器獲取 ticket

image

第二次,從緩存中:

image

至此,我們獲取到了 jsapi_ticker;

獲得jsapi_ticket之后,就可以生成JS-SDK權限驗證的簽名了

4、增加簽名算法獲取微信簽名

簽名算法

簽名生成規則如下:參與簽名的字段包括noncestr(隨機字符串), 有效的jsapi_ticket, timestamp(時間戳), url(當前網頁的URL,不包含#及其后面部分) 。對所有待簽名參數按照字段名的ASCII 碼從小到大排序(字典序)后,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1。這里需要注意的是所有參數名均為小寫字符。對string1sha1加密,字段名和字段值都采用原始值,不進行URL 轉義。

說明:

noncestr隨機字符串,一般自己生成

jsapi_ticket 從微信服務器或者自己的緩存中

timestamp時間戳自己生成

url當前頁面的url,一定要動態獲取,千萬不要 hardcode

然后再按照字典排序,進行排序 jsapi_ticket&noncestr&timestamp&url

最后sha1 加密

signature=sha1(string1)。 示例:

noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3
timestamp=1414587457
url=http://mp.weixin.qq.com?params=value

步驟1. 對所有待簽名參數按照字段名的ASCII 碼從小到大排序(字典序)后,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1

jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value

步驟2. 對string1進行sha1簽名,得到signature

0f9de62fce790f9a083d5c99e95740ceb90c27ed

注意事項

1.簽名用的noncestrtimestamp必須與wx.config中的nonceStrtimestamp相同。

2.簽名用的url必須是調用JS接口頁面的完整URL

3.出于安全考慮,開發者必須在服務器端實現簽名的邏輯。

如出現invalid signature 等錯誤詳見附錄常見錯誤及解決辦法

代碼如下:

/**
 * 獲取簽名
 * @returns:
 * 1. appId 必填,公眾號的唯一標識
 * 2. timestamp 必填,生成簽名的時間戳
 * 3. nonceStr 必填,生成簽名的隨機串
 * 4. signature 必填,簽名
 */
const crypto = require('crypto');
const config = require('../config/index.json');

// sha1加密
function sha1(str) {
  let shasum = crypto.createHash("sha1")
  shasum.update(str)
  str = shasum.digest("hex")
  return str
}

/**
 * 生成簽名的時間戳
 * @return {字符串}
 */
function createTimestamp() {
  return parseInt(new Date().getTime() / 1000) + ''
}

/**
 * 生成簽名的隨機串
 * @return {字符串}
 */
function createNonceStr() {
  return Math.random().toString(36).substr(2, 15)
}

/**
 * 對參數對象進行字典排序
 * @param  {對象} args 簽名所需參數對象
 * @return {字符串}    排序后生成字符串
 */
function raw(args) {
  var keys = Object.keys(args)
  keys = keys.sort()
  var newArgs = {}
  keys.forEach(function (key) {
    newArgs[key.toLowerCase()] = args[key]
  })

  var string = ''
  for (var k in newArgs) {
    string += '&' + k + '=' + newArgs[k]
  }
  string = string.substr(1)
  return string
}


module.exports = getSign = (params, res) => {

  /**
   * 簽名算法
   * 簽名生成規則如下:
   * 參與簽名的字段包括noncestr( 隨機字符串),
   * 有效的jsapi_ticket, timestamp( 時間戳),
   * url( 當前網頁的URL, 不包含# 及其后面部分)。
   * 對所有待簽名參數按照字段名的ASCII 碼從小到大排序( 字典序) 后,
   *  使用URL鍵值對的格式( 即key1 = value1 & key2 = value2…) 拼接成字符串string1。
   * 這里需要注意的是所有參數名均為小寫字符。 對string1作sha1加密, 字段名和字段值都采用原始值, 不進行URL 轉義。
   */
  var ret = {
    jsapi_ticket: params.ticket,
    nonceStr: createNonceStr(),
    timestamp: createTimestamp(),
    url: params.url
  };
  console.log(params, ret);
  var string = raw(ret)
  ret.signature = sha1(string)
  ret.appId = config.appid;
  console.log('ret', ret)
  res.send(ret);
}

路由設置:

const express = require('express');
const api = require('./api');
const path = require('path');
const app = express();
//express請求別的路由中間件
require('run-middleware')(app);

//獲取簽名
app.get('/sign', (req, res) => {
  const params = {};
  console.log(req.query)
  params.url = req.query.url;
  /***
   * runMiddleware 請求別的 endPoint 獲取 jsapi_ticket
   */
  app.runMiddleware('/getTicket', function (code, body, headers) {
    const result = JSON.parse(body);
    console.log('User ticket:', result.ticket);
    params.ticket = result.ticket;
    api.getSign(params, res);
  });

});

....

postman 請求如下:

image

這樣我就獲取了 簽名 等一系列數據。

5、JSSDK 使用

微信JS-SDK說明文檔

步驟一:綁定域名

先登錄微信公眾平臺進入“公眾號設置”的“功能設置”里填寫“JS接口安全域名”。

備注:登錄后可在“開發者中心”查看對應的接口權限。

步驟二:引入JS文件

在需要調用JS接口的頁面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.4.0.js

如需進一步提升服務穩定性,當上述資源不可訪問時,可改訪問:http://res2.wx.qq.com/open/js/jweixin-1.4.0.js (支持https)。

備注:支持使用 AMD/CMD 標準模塊加載方法加載

步驟三:通過config接口注入權限驗證配置

所有需要使用JS-SDK的頁面必須先注入配置信息,否則將無法調用(同一個url僅需調用一次,對于變化url的SPA的web app可在每次url變化時進行調用,目前Android微信客戶端不支持pushState的H5新特性,所以使用pushState來實現web app的頁面會導致簽名失敗,此問題會在Android6.2中修復)。

wx.config({
    debug: true, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會打印。
    appId: '', // 必填,公眾號的唯一標識
    timestamp: , // 必填,生成簽名的時間戳
    nonceStr: '', // 必填,生成簽名的隨機串
    signature: '',// 必填,簽名
    jsApiList: [] // 必填,需要使用的JS接口列表
});

步驟四:通過ready接口處理成功驗證

wx.ready(function(){
    // config信息驗證后會執行ready方法,所有接口調用都必須在config接口獲得結果之后,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在ready函數中調用來確保正確執行。對于用戶觸發時才調用的接口,則可以直接調用,不需要放在ready函數中。
});

實戰代碼如下:

// promise
const getSignPromise = new Promise((resolve, reject) => {
  const xhr = new XMLHttpRequest();
  xhr.open('GET', location.origin + '/sign?url=' + location.href, true);
  xhr.send();
  xhr.onload = () => {
    if (xhr.readyState === xhr.DONE) {
      if (xhr.status === 200) {
        const result = JSON.parse(xhr.response);
        console.log(result);
        resolve(result);
      }
    }
  }
});

// 分享
getSignPromise.then(res => {
  getWeShare(res);
});

/***
 * 微信分享
 */
const getWeShare = (params) => {
  wx.config({
    debug: true, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會打印。
    appId: params.appId, // 必填,公眾號的唯一標識
    timestamp: params.timestamp, // 必填,生成簽名的時間戳
    nonceStr: params.nonceStr, // 必填,生成簽名的隨機串
    signature: params.signature, // 必填,簽名
    jsApiList: [
      'checkJsApi',
      'onMenuShareTimeline',
      'onMenuShareAppMessage',
      'onMenuShareQQ',
      'onMenuShareWeibo',
      'hideMenuItems',
      'chooseImage',
      'updateAppMessageShareData',
      'scanQRCode'
    ] // 必填,需要使用的JS接口列表
  });

  wx.ready(function () { //需在用戶可能點擊分享按鈕前就先調用
    const data = {
      title: '測試JSSDK', // 分享標題
      desc: '后端端口簽名測試', // 分享描述
      link: location.href, // 分享鏈接,該鏈接域名或路徑必須與當前頁面對應的公眾號JS安全域名一致
      imgUrl: 'http://www.***.cf/img/share.JPG', // 分享圖標
      success: function () {
        // 設置成功
      }
    }
    wx.onMenuShareTimeline(data);
    wx.onMenuShareAppMessage(data);
  });
}

// 打開相冊
document.getElementById('chooseImage').addEventListener('click', function (params) {
  wx.chooseImage({
    count: 1, // 默認9
    sizeType: ['original', 'compressed'], // 可以指定是原圖還是壓縮圖,默認二者都有
    sourceType: ['album', 'camera'], // 可以指定來源是相冊還是相機,默認二者都有
    success: function (res) {
      var localIds = res.localIds; // 返回選定照片的本地ID列表,localId可以作為img標簽的src屬性顯示圖片
      console.log(localIds);
    }
  });
  wx.scanQRCode({
    needResult: 0, // 默認為0,掃描結果由微信處理,1則直接返回掃描結果,
    scanType: ["qrCode", "barCode"], // 可以指定掃二維碼還是一維碼,默認二者都有
    success: function (res) {
      var result = res.resultStr; // 當needResult 為 1 時,掃碼返回的結果
    }
  });
})

頁面寫好之后, 我們可以在 微信開發者工具里面看到:

image
image

我們也可以打開測試公眾號,在里面調試,否則,我們沒有權限調取 js 接口

image
image
image

至此,已經算是成功開發了,其他接口不再做嘗試。

6、附錄

調用config接口的時候傳入參數 debug: true 可以開啟debug模式,頁面會alert出錯誤信息。以下為常見錯誤及解決方法:

1.invalid url domain當前頁面所在域名與使用的appid沒有綁定,請確認正確填寫綁定的域名,僅支持80(http)443(https)兩個端口,因此不需要填寫端口號(一個appid可以綁定三個有效域名,見 ]目錄1.1.1)。

2.·invalid signature簽名錯誤。建議按如下順序檢查:

1.確認簽名算法正確,可用http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 頁面工具進行校驗。

2.確認confignonceStr(js中駝峰標準大寫S), timestamp與用以簽名中的對應noncestr, timestamp一致。

3.確認url是頁面完整的url(請在當前頁面alert(location.href.split('#')[0])確認),包括'http(s)://'部分,以及'?'后面的GET參數部分,但不包括'#'hash后面的部分。

4.確認 config 中的 appid 與用來獲取 jsapi_ticket 的 appid 一致。

5.確保一定緩存access_tokenjsapi_ticket

6.確保你獲取用來簽名的url是動態獲取的,動態頁面可參見實例代碼中php的實現方式。如果是html的靜態頁面在前端通過ajax將url傳到后臺簽名,前端需要用js獲取當前頁面除去'#'hash部分的鏈接(可用location.href.split('#')[0]獲取,而且需要encodeURIComponent),因為頁面一旦分享,微信客戶端會在你的鏈接末尾加入其它參數,如果不是動態獲取當前鏈接,將導致分享后的頁面簽名失敗。

3.the permission value is offline verifying這個錯誤是因為config沒有正確執行,或者是調用的JSAPI沒有傳入config的jsApiList參數中。建議按如下順序檢查:

1.確認config正確通過。

2.如果是在頁面加載好時就調用了JSAPI,則必須寫在wx.ready的回調中。

3.確認config的jsApiList參數包含了這個JSAPI。

4.permission denied該公眾號沒有權限使用這個JSAPI,或者是調用的JSAPI沒有傳入config的jsApiList參數中(部分接口需要認證之后才能使用)。

5.function not exist當前客戶端版本不支持該接口,請升級到新版體驗。

6.為什么6.0.1版本config:ok,但是6.0.2版本之后不ok(因為6.0.2版本之前沒有做權限驗證,所以config都是ok,但這并不意味著你config中的簽名是OK的,請在6.0.2檢驗是否生成正確的簽名以保證config在高版本中也ok。)

7.在iOS和Android都無法分享(請確認公眾號已經認證,只有認證的公眾號才具有分享相關接口權限,如果確實已經認證,則要檢查監聽接口是否在wx.ready回調函數中觸發)

8.服務上線之后無法獲取jsapi_ticket,自己測試時沒問題。(因為access_token和jsapi_ticket必須要在自己的服務器緩存,否則上線后會觸發頻率限制。請確保一定對token和ticket做緩存以減少2次服務器請求,不僅可以避免觸發頻率限制,還加快你們自己的服務速度。目前為了方便測試提供了1w的獲取量,超過閥值后,服務將不再可用,請確保在服務上線前一定全局緩存access_token和jsapi_ticket,兩者有效期均為7200秒,否則一旦上線觸發頻率限制,服務將不再可用)。

9.uploadImage怎么傳多圖(目前只支持一次上傳一張,多張圖片需等前一張圖片上傳之后再調用該接口)

10.沒法對本地選擇的圖片進行預覽(chooseImage接口本身就支持預覽,不需要額外支持)

11.通過a鏈接(例如先通過微信授權登錄)跳轉到b鏈接,invalid signature簽名失敗(后臺生成簽名的鏈接為使用jssdk的當前鏈接,也就是跳轉后的b鏈接,請不要用微信登錄的授權鏈接進行簽名計算,后臺簽名的url一定是使用jssdk的當前頁面的完整url除去'#'部分)

12.出現config:fail錯誤(這是由于傳入的config參數不全導致,請確保傳入正確的appId、timestamp、nonceStr、signature和需要使用的jsApiList)

13.如何把jsapi上傳到微信的多媒體資源下載到自己的服務器(請參見文檔中uploadVoice和uploadImage接口的備注說明)

14.Android通過jssdk上傳到微信服務器,第三方再從微信下載到自己的服務器,會出現雜音(微信團隊已經修復此問題,目前后臺已優化上線)

15.綁定父級域名,是否其子域名也是可用的(是的,合法的子域名在綁定父域名之后是完全支持的)

16.在iOS微信6.1版本中,分享的圖片外鏈不顯示,只能顯示公眾號頁面內鏈的圖片或者微信服務器的圖片,已在6.2中修復

17.是否需要對低版本自己做兼容(jssdk都是兼容低版本的,不需要第三方自己額外做更多工作,但有的接口是6.0.2新引入的,只有新版才可調用)

18.該公眾號支付簽名無效,無法發起該筆交易(請確保你使用的jweixin.js是官方線上版本,不僅可以減少用戶流量,還有可能對某些bug進行修復,拷貝到第三方服務器中使用,官方將不對其出現的任何問題提供保障,具體支付簽名算法可參考 JSSDK微信支付一欄)

19.目前Android微信客戶端不支持pushState的H5新特性,所以使用pushState來實現web app的頁面會導致簽名失敗,此問題已在Android6.2中修復

20.uploadImage在chooseImage的回調中有時候Android會不執行,Android6.2會解決此問題,若需支持低版本可以把調用uploadImage放在setTimeout中延遲100ms解決

21.require subscribe錯誤說明你沒有訂閱該測試號,該錯誤僅測試號會出現

22.getLocation返回的坐標在openLocation有偏差,因為getLocation返回的是gps坐標,openLocation打開的騰訊地圖為火星坐標,需要第三方自己做轉換,6.2版本開始已經支持直接獲取火星坐標

23.查看公眾號(未添加): "menuItem:addContact"不顯示,目前僅有從公眾號傳播出去的鏈接才能顯示,來源必須是公眾號

24.ICP備案數據同步有一天延遲,所以請在第二日綁定

DEMO頁面和示例代碼

DEMO頁面:

http://demo.open.weixin.qq.com/jssdk

image

示例代碼:

http://demo.open.weixin.qq.com/jssdk/sample.zip

備注:鏈接中包含php、java、nodejs以及python的示例代碼供第三方參考,第三方切記要對獲取的accesstoken以及jsapi_ticket進行緩存以確保不會觸發頻率限制。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,619評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,155評論 3 425
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,635評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,539評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,255評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,646評論 1 326
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,655評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,838評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,399評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,146評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,338評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,893評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,565評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,983評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,257評論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,059評論 3 397
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,296評論 2 376

推薦閱讀更多精彩內容

  • 先引入JS 文件 this.wxShare() 在created里調用 首先登陸微信公眾號 JSSDK使用步驟 步...
    寄魚予海與你閱讀 6,727評論 1 3
  • 1. 準備工作 1.1 查看公眾號分享接口權限 要使用微信SDK必須要有經過微信認證的非個人服務號 登陸服務號后,...
    sxplus閱讀 6,311評論 0 2
  • 微信服務號開發 整體流程 域名報備,服務器搭建 Python開發環境和項目的初始化搭建; 微信公眾號注冊及開發模式...
    飛行員suke閱讀 4,565評論 0 14
  • 每天晚上開一會兒空調的并不太涼快的時候也是很難得的 真是涼風有興咧 然而中午最熱的時候沒有空調關門關窗風扇一檔真是...
    蔣一句閱讀 169評論 0 0
  • 李國陽閱讀 136評論 0 0