微信公眾號(hào)開發(fā)——JS-SDK掃一掃接口調(diào)用

概述

微信JS-SDK是微信公眾平臺(tái) 面向網(wǎng)頁開發(fā)者提供的基于微信內(nèi)的網(wǎng)頁開發(fā)工具包髓考。
通過使用微信JS-SDK妓湘,網(wǎng)頁開發(fā)者可借助微信高效地使用拍照、選圖、語音、位置等手機(jī)系統(tǒng)的能力,同時(shí)可以直接使用微信分享、掃一掃、卡券砂心、支付等微信特有的能力译暂,為微信用戶提供更優(yōu)質(zhì)的網(wǎng)頁體驗(yàn)伯顶。

相應(yīng)官方文檔

微信公眾平臺(tái)開發(fā)文檔
JS-SDK說明文檔

接口調(diào)用步驟(整體步驟相對(duì)還是比較簡(jiǎn)單的)

  • 1.配置JS接口安全域名(此處類似于搭建微信測(cè)試號(hào),可通過Natapp等映射工具實(shí)現(xiàn))


  • 2.JS-SDK驗(yàn)證(具體步驟會(huì)在代碼中標(biāo)明)
  • 3.調(diào)起微信掃一掃接口

調(diào)用思路:

1.驗(yàn)證JS-SDK
  • 官網(wǎng)文檔


    來源JS-SDK說明文檔附錄6
  • 下載后的示例代碼
import java.util.UUID;
import java.util.Map;
import java.util.HashMap;
import java.util.Formatter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.io.UnsupportedEncodingException;  

class Sign {
    public static void main(String[] args) {
        String jsapi_ticket = "jsapi_ticket";

        // 注意 URL 一定要?jiǎng)討B(tài)獲取,不能 hardcode
        String url = "http://example.com";
        Map<String, String> ret = sign(jsapi_ticket, url);
        for (Map.Entry entry : ret.entrySet()) {
            System.out.println(entry.getKey() + ", " + entry.getValue());
        }
    };

    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 = "";

        //注意這里參數(shù)名必須全部小寫碎连,且必須有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
                  "&noncestr=" + nonce_str +
                  "&timestamp=" + timestamp +
                  "&url=" + url;
        System.out.println(string1);

        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;
    }

/**
     * 隨機(jī)加密
     *
     * @param hash
     * @return
     */
    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;
    }

 /**
     * 產(chǎn)生隨機(jī)串--由程序自己隨機(jī)產(chǎn)生
     *
     * @return
     */
    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

 /**
     * 由程序自己獲取當(dāng)前時(shí)間
     *
     * @return
     */
    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}
2. 最主要的步驟:集齊示例所需的參數(shù)
  url     jsapi_ticket      nonceStr(已有)    timestamp(已有)    signature
請(qǐng)注意劃重點(diǎn)的地方
3.jsapi_ticket 的獲取:
  • 獲取JS-SDK的 accesstoken (注意:其與獲取網(wǎng)頁授權(quán)的accesstoken不同)
        JSONObject accesTokenObject = JSONObject.fromObject(Doget.get(ACCESS_TOKEN_URL));
        String accesToken = (String) accesTokenObject.get("access_token");
        System.out.println("微信返回的accesToken" + accesToken);
  • 獲取jsapiTicket
 JSONObject jsapiTicketObject = JSONObject.fromObject(Doget.get("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accesToken + "&type=jsapi"));
        String jsapiTicket = (String) jsapiTicketObject.get("ticket");
        System.out.println("微信返回的jsapiTicket" + jsapiTicket);
  • 最后對(duì)官網(wǎng)給的示例進(jìn)行修改即可

源碼(直接復(fù)制就可使用)

  • URL請(qǐng)求類
package com.itcast.util.wechatUtil;

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

public class Doget {

    /**
     * 功能描述:向指定地址發(fā)送get請(qǐng)求 (**發(fā)送get請(qǐng)求地址的時(shí)候基本都會(huì)去調(diào)用到**)
     *
     * @param url
     * @date: 2019/1/13 15:27
     * @return:
     */

    public static String get(String url) {
        try {
            URL urlObj = new URL(url);
            //開連接
            URLConnection urlConnection = urlObj.openConnection();
            //讀取返回的JSON對(duì)象
            InputStream inputStream = urlConnection.getInputStream();
            byte[] b = new byte[1024];
            int leng;
            StringBuilder sb = new StringBuilder();
            while ((leng = inputStream.read(b)) != -1) {
                sb.append(new String(b, 0, leng));
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
  • 完善后的SignUtil
import net.sf.json.JSONObject;

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 class SignUtil {
    public static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + SignUtil.APPID + "&secret=" + SignUtil.APPSECRET + "";

    public static Map<String, String> sign(String url) {
        //獲取JS-SDK的 accesstoken 注意:其與獲取網(wǎng)頁授權(quán)的accesstoken不同
        JSONObject accesTokenObject = JSONObject.fromObject(Doget.get(ACCESS_TOKEN_URL));
        String accesToken = (String) accesTokenObject.get("access_token");
        System.out.println("微信返回accesToken" + accesToken);

        //獲取ticket
        JSONObject jsapiTicketObject = JSONObject.fromObject(Doget.get("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accesToken + "&type=jsapi"));
        String jsapiTicket = (String) jsapiTicketObject.get("ticket");
        System.out.println("微信返回jsapiTicket" + jsapiTicket);

        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";

        //注意這里參數(shù)名必須全部小寫驳概,且必須有序
        string1 = "jsapi_ticket=" + jsapiTicket +
                "&noncestr=" + nonce_str +
                "&timestamp=" + timestamp +
                "&url=" + url;
        System.out.println("string1=" + string1);

        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();
        } catch (Exception e) {
            e.printStackTrace();
        }

        ret.put("url", url);
        ret.put("jsapi_ticket", jsapiTicket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        ret.put("appId", 你的APPID);  //此時(shí)可通過配置引入

        System.out.println("1.ticket(原始)=" + jsapiTicket);
        System.out.println("2.url=" + ret.get("url"));
        System.out.println("3.jsapi_ticket(處理后)=" + ret.get("jsapi_ticket"));
        System.out.println("4.nonceStr=" + ret.get("nonceStr"));
        System.out.println("5.signature=" + ret.get("signature"));
        System.out.println("6.timestamp=" + ret.get("timestamp"));

        return ret;
    }

    /**
     * 隨機(jī)加密
     *
     * @param hash
     * @return
     */
    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;
    }

    /**
     * 產(chǎn)生隨機(jī)串--由程序自己隨機(jī)產(chǎn)生
     *
     * @return
     */
    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    /**
     * 由程序自己獲取當(dāng)前時(shí)間
     *
     * @return
     */
    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}
  • 控制層代碼(主要就是獲取URL進(jìn)行JS-SDK驗(yàn)證)
  @RequestMapping("/getwechatscan")
    @ResponseBody
    public Result wechatscan(@RequestParam String URL) {
        //轉(zhuǎn)義
        String urlDecode = URLDecoder.decode(URL);
        Map<String, String> map = JsSignUtil.sign(urlDecode);
        return Result.success(map);
    }
  • 前端接口調(diào)用代碼
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <meta charset="UTF-8">
    <title>微信掃一掃</title>
    <%--步驟二:引入JS文件--%>
    <script src="http://res2.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
</head>
<body>

<input type="text" id="tesss">
<button id="scanQRCode" onclick="getWeixinResult()">掃描二維碼</button>
</body>
<script>
    $(document).ready(function () {
        getWeixinParams();
    });

    //微信JS—SDK驗(yàn)證
    function getWeixinParams() {
        //不帶參數(shù)URL
        // var WX_url = window.location.origin + window.location.pathname;
        //請(qǐng)求地址
        alert(window.location.origin);
        //請(qǐng)求方法
        alert(window.location.pathname);
        //帶參數(shù)URL
        var WX_url = location.href.split('#')[0];
        alert(WX_url);
        $.ajax({
            type: "post",
            url: "/getwechatscan",
            data: {"URL": WX_url},
            datatype: "json",
            success: function (data) {
                var appId = data.data.appId;
                var nonceStr = data.data.nonceStr;
                var signature = data.data.signature;
                var timestamp = data.data.timestamp;
                getWeixinParamsCallBack(appId, timestamp, nonceStr, signature);
            },
            error: function () {
                alert("出錯(cuò)了");
            }
        });
    }
    //選擇要調(diào)用的接口 接口名稱
    function getWeixinParamsCallBack(appId, timestamp, nonceStr, signature) {
//步驟三:通過config接口注入權(quán)限驗(yàn)證配置       
 wx.config({
            debug: true, // 開啟調(diào)試模式,調(diào)用的所有api的返回值會(huì)在客戶端alert出來雕憔,若要查看傳入的參數(shù)琉苇,可以在pc端打開抡诞,參數(shù)信息會(huì)通過log打出顷窒,僅在pc端時(shí)才會(huì)打印。
            appId: appId, // 必填,公眾號(hào)的唯一標(biāo)識(shí)
            timestamp: timestamp, // 必填,生成簽名的時(shí)間戳
            nonceStr: nonceStr, // 必填系瓢,生成簽名的隨機(jī)串
            signature: signature, // 必填骗绕,簽名
            jsApiList: ['scanQRCode'] // 必填格带,需要使用的JS接口列表
        });
       //步驟四:通過ready接口處理成功驗(yàn)證(可不寫 這里只是跟你說配置成功而已)
        wx.ready(function () {
            alert("成功配置了微信JS");
        });
        //步驟五:通過error接口處理失敗驗(yàn)證
        wx.error(function (res) {
            alert("相應(yīng)數(shù)據(jù)獲取出錯(cuò)了:" + res.errMsg);
        });
    }

    function getWeixinResult() {
        //調(diào)取接口
        wx.scanQRCode({
            needResult: 1, // 默認(rèn)為0,掃描結(jié)果由微信處理镶摘,1則直接返回掃描結(jié)果种樱,
//            desc: 'scanQRCode desc',
            scanType: ["qrCode", "barCode"], // 可以指定掃二維碼還是一維碼岂昭,默認(rèn)二者都有
            success: function (res) {
                var result = res.resultStr; // 當(dāng)needResult 為 1 時(shí)恰矩,掃碼返回的結(jié)果
                if (result.indexOf("=") != -1) {
                    result = result.split("=")[1];
                } else if (result.indexOf(",") != -1) {
                    result = result.split(",")[1];
                }

                $("#tesss").val(result);
//                alert("掃描成功::掃描碼=" + result);
            }
        });
    }

</script>
</html>
  • 結(jié)果

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末萎胰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌遣妥,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異本辐,居然都是意外死亡茫多,警方通過查閱死者的電腦和手機(jī)歉甚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門镣陕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岂嗓,“玉大人,你說我怎么就攤上這事。” “怎么了硝清?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵扰藕,是天一觀的道長(zhǎng)染乌。 經(jīng)常有香客問我褐望,道長(zhǎng)勒庄,這世上最難降的妖魔是什么串前? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮实蔽,結(jié)果婚禮上荡碾,老公的妹妹穿的比我還像新娘。我一直安慰自己局装,他們只是感情好坛吁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著铐尚,像睡著了一般拨脉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宣增,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天玫膀,我揣著相機(jī)與錄音,去河邊找鬼爹脾。 笑死帖旨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的灵妨。 我是一名探鬼主播解阅,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼泌霍!你這毒婦竟也來了瓮钥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤烹吵,失蹤者是張志新(化名)和其女友劉穎碉熄,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肋拔,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锈津,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了凉蜂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琼梆。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖窿吩,靈堂內(nèi)的尸體忽然破棺而出茎杂,到底是詐尸還是另有隱情,我是刑警寧澤纫雁,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布煌往,位于F島的核電站,受9級(jí)特大地震影響轧邪,放射性物質(zhì)發(fā)生泄漏刽脖。R本人自食惡果不足惜羞海,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望曲管。 院中可真熱鬧却邓,春花似錦、人聲如沸院水。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽檬某。三九已至撬腾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間橙喘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工胶逢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厅瞎,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓初坠,卻偏偏與公主長(zhǎng)得像和簸,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子碟刺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 最近接受了一個(gè)新的需求锁保,希望制作一個(gè)基于微信的英語語音評(píng)價(jià)頁面。即點(diǎn)擊錄音按鈕半沽,用戶錄音說出預(yù)設(shè)的英文爽柒,根據(jù)用戶的...
    ReeCode閱讀 9,133評(píng)論 7 15
  • 點(diǎn)擊查看原文 Web SDK 開發(fā)手冊(cè) SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個(gè)完善的 IM 系統(tǒng)...
    layjoy閱讀 13,772評(píng)論 0 15
  • 最近又在vue中搗鼓了下微信公眾號(hào)api的接入,不得不說這里邊水是真的深啊者填,上次分享了微信授權(quán)登錄和js-sdk簽...
    imwty閱讀 16,711評(píng)論 2 15
  • 前題 本篇適用范圍: 使用微信JS-SDK接口調(diào)用浩村,分享朋友圈、朋友占哟、QQ心墅、QQ空間、騰訊微博等榨乎,包括分享鏈接中帶...
    登上云端看日落閱讀 820評(píng)論 1 1
  • 昨天被三個(gè)朋友拒絕和質(zhì)疑怎燥,心理不舒服,找老公尋求支持蜜暑,結(jié)果他和別人一樣質(zhì)疑铐姚,說自己被洗腦了,做傳銷了肛捍,很失望谦屑,很憤...
    云的成長(zhǎng)閱讀 160評(píng)論 0 0