示例是在JS調起微信掃一掃,掃描二維碼並獲取掃描結果!
1.首先是微信公衆號綁定JS接口安全域名 , 直接放文檔鏈接。 (文檔步驟一)
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#2
2.H5獲取JSP 引入JS文件 (文檔步驟二)
在需要調用JS接口的頁面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js
如需進一步提升服務穩定性,當上述資源不可訪問時,可改訪問:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)。
3.通過config接口注入權限驗證配置 (文檔步驟三)
因爲文檔有詳細說明,只講一下遇到的問題。
我當時是在,頁面點擊按鈕的時候進行配置,然後再調起掃一掃接口。然後config返回invalid signature簽名錯誤。
當時這個問題找了很久,不管是配置信息還是簽名,是沒有問題的。最後解決辦法是將config接口在JS 頁面加載的時候
先進行配置,點擊按鈕的時候就直接調起掃一掃接口,就完美解決了。
wx.config接口就是微信的配置接口。
這裏通過頁面加載獲取 配置的簽名信息。後臺代碼放第4點。
$(function (){
// 獲取當前url
var url = location.href.split('#')[0];
var p = {m:"GETWECHATSCANINFO",url:url};
var res = ajaxAssistant("wechat.action",p);
if(res.code == 1000){
res = $.parseJSON(res.msg);
wxCfg(res.appId,res.timestamp,res.nonceStr,res.signature);
}
return false;
});
//配置wx js
function wxCfg(_appid,_timestamp, _nonceStr, _signature) {
wx.config({
debug :false,// 調試模式,調用的所有api的返回值會在客戶端alert出來。true開啓
appId : _appid,// 必填,公衆號的唯一標識,公衆號後臺唯一標識
timestamp : _timestamp,// 必填,生成簽名的時間戳 要與後臺生成的簽名一致。所以是傳過來的
nonceStr : _nonceStr,// 必填,生成簽名的隨機串 也跟後臺生成的簽名一致。
signature : _signature,// 必填,簽名
jsApiList : ['checkJsApi', 'scanQRCode']// 必填,需要使用的JS接口列表,checkJsApi必填
});
}
4.獲取微信 api_ticket
api_ticket 是用於調用微信JS API的臨時票據,有效期爲7200 秒,通過access_token 來獲取。
access_token就不想講了,網上很多。
開發者注意事項:
1.此用於卡券接口簽名的api_ticket與步驟三中通過config接口注入權限驗證配置使用的jsapi_ticket不同。
2.由於獲取api_ticket 的api 調用次數非常有限,頻繁刷新api_ticket 會導致api調用受限,影響自身業務,開發者需在自己的服務存儲與更新api_ticket。
接口調用請求說明
http請求方式: GET https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=wx_card
public static String getTicket(String access_token){
String jsapi_ticket = "";
try {
// token有效期 CacheUtil是封裝起來的 Map集合
Object time = CacheUtil.get(TICKET_TIME_KEY);
boolean isReToken = false;
if (null!=time) {
// ticket 有效期 7200秒 120分鐘 這裏過了 100分鐘獲取一次 , 理論1小時可獲取400次 但還是緩存起來
boolean isE = isExpired(time.toString(), 100);
isReToken = isE;
} else {
isReToken =!isReToken;
}
// true 重新獲取
if (isReToken) {
String requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
String response = HttpUtil.instanse().quickGetUrl(requestUrl, 10);
JSONObject res = DataUtil.string2JSONObject(response);
log.debug("#get_jsapi_ticket result is -> "+response);
if(res.containsKey("ticket")){
jsapi_ticket = res.getString("ticket");
// 緩存時間戳 或 token
CacheUtil.set(TICKET_TOKEN_KEY,jsapi_ticket);
CacheUtil.set(TICKET_TIME_KEY, System.currentTimeMillis());
}
} else {
jsapi_ticket = CacheUtil.getString(TICKET_TOKEN_KEY);
}
} catch (Exception e) {
log.debug("#request get_jsapi_ticket has error,",e);
}
return jsapi_ticket;
}
/**
* 驗證時間戳
* @param tokenAging 時間戳
* @param m 驗證超過的時間(分鐘)
* @return true 超過
*/
public static boolean isExpired (String tokenAging,int m) {
boolean is = false;
Date date = new Date(Long.parseLong(tokenAging));
Long minute =(System.currentTimeMillis() - date.getTime()) / (1000 * 60); // 分鐘爲單位
if (minute > m) {
is = true;
}
return is;
}
5.根據api_ticket 進行簽名簽名 SHA-1 簽名
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public static Map<String, String> sign(String jsapi_ticket, String url) {
Map<String, String> ret = new HashMap<String, String>();
// 字符串隨機數
String nonce_str = create_nonce_str();
// 時間戳(秒)
String timestamp = create_timestamp();
String string1;
String signature = "";
//注意這裏參數名必須全部小寫,且必須有序
string1 = "jsapi_ticket=" + jsapi_ticket +
"&noncestr=" + nonce_str +
"×tamp=" + timestamp +
"&url=" + url;
try
{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
ret.put("url", url);
ret.put("jsapi_ticket", jsapi_ticket);
ret.put("nonceStr", nonce_str);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
return ret;
}
private static String byteToHex(final byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash)
{
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
private static String create_nonce_str() {
return UUID.randomUUID().toString();
}
private static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
6.最後可以調用微信掃一掃接口了
// 調起掃一掃 這裏是點擊掃一掃按鈕的事件方法
function wxScan() {
wx.ready(function() {//配置文件加載完成之後會自動調用ready中的模塊
wx.checkJsApi({
jsApiList : ['scanQRCode'],
success : function(res) {
wx.scanQRCode({
// 默認爲0,掃描結果由微信處理,1則直接返回掃描結果,
needResult: 1,
// 可以指定掃二維碼還是一維碼,默認二者都有
scanType: ["qrCode","barCode"],
success: function (res) {
// result 這裏直接返回二維碼中的內容,根據內容可以做自己的業務了
// needResult爲1 時
var val = res.resultStr;
}
});
}
});
});
wx.error(function(res) {
alert("掃一掃調起失敗:" + res.errMsg+",請重試!");
});
}
7.常見錯誤
這裏就直接放官方文檔了,因爲自己沒遇到過。
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#66
個人博客:unclepig.top