微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。

通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,

同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。


首先需要配置JS接口安全域名

8.png


在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.2.0.js,然后配置

wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,公众号的唯一标识
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名
    jsApiList: [] // 必填,需要使用的JS接口列表
});

这么多配置项目,对应该怎么填呢?主要代码

/**
 * 生成签名
 * @return array
 */
public function getSignPackage() {
    $jsapiTicket = $this->getJsApiTicket();

    // 注意 URL 一定要动态获取
    $protocol  = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
    $url       = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
    $timestamp = time();
    // 生成随机字符
    $nonceStr  = $this->createNonceStr();

    // 这里参数的顺序要按照 key 值 ASCII 码升序排序
    $string    = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
    $signature = sha1($string);

    $signPackage = [
        "appId"   => self::APPID,
        "nonceStr"  => $nonceStr,
        "timestamp" => $timestamp,
        "signature" => $signature
    ];

    // 这里就是JSSDK中需要用到的配置
    return $signPackage;
}

/**
 * 获取临时票据
 * @return mixed
 */
private function getJsApiTicket() {
    $ticketCache  = $this->getCache('ticket');

    if (!$ticketCache) {
        $token  = $this->getAccessToken();
        $url    = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$token.'&type=jsapi';
        $result = json_decode($this->http_request($url), true);

        $ticket = $result['ticket'];
        $this->setCache('ticket', $ticket, $result['expires_in']);
    } else {
        $ticket = $ticketCache['value'];
    }

    return $ticket;
}


javascript代码

<button type="button" id="scanQRCode">点我扫码</button>

<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script type="text/javascript">
    wx.config({
        debug: true,
        appId: '',
        timestamp: 1525775643,
        nonceStr: 'HopIrZIFaPWYKJOE',
        signature: '',
        jsApiList: [
            'scanQRCode'
        ]
    });

    document.querySelector('#scanQRCode').onclick = function () {
        wx.scanQRCode({
            needResult: 1,
            desc: 'scanQRCode desc',
            success: function (res) {
                alert(JSON.stringify(res));//打印二维码信息
            }
        });
    };
</script>

在测试的过程中,你会发现无论你怎么调,都没有debug信息,怎么回事呢,原来我们需要在jsApiList中加入一些接口,才能调出调试信息,例如上面加入了scanQRCode这个接口

如果提示“invalid url domain”,那么说明你的'JS接口安全域名'没有配置成功,请不要加‘http://’,域名后面也不要加任何目录。如果出现下面的提示说明配置成功。


9.png



全部代码

<?php
require APP_PATH . '/Controller/CommonController.php';

/*
 * 注意:
 * 1. 所有的JS接口只能在公众号绑定的域名下调用,公众号开发者需要先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
 * 2. 如果发现在 Android 不能分享自定义内容,请到官网下载最新的包覆盖安装,Android 自定义分享接口需升级至 6.0.2.58 版本及以上。
 * 3. 常见问题及完整 JS-SDK 文档地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html
 *
 * 开发中遇到问题详见文档“附录5-常见错误及解决办法”解决,如仍未能解决可通过以下渠道反馈:
 * 邮箱地址:weixin-open@qq.com
 * 邮件主题:【微信JS-SDK反馈】具体问题
 * 邮件内容说明:用简明的语言描述问题所在,并交代清楚遇到该问题的场景,可附上截屏图片,微信团队会尽快处理你的反馈。
 * <script src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
 * wx.config({
    debug: true,
    appId: '<?php echo $signPackage["appId"];?>',
    timestamp: <?php echo $signPackage["timestamp"];?>,
    nonceStr: '<?php echo $signPackage["nonceStr"];?>',
    signature: '<?php echo $signPackage["signature"];?>',
    jsApiList: [
      // 所有要调用的 API 都要加到这个列表中
    ]
  });
  wx.ready(function () {
    // 在这里调用 API
  });
*/
class JssdkController extends CommonController
{
    // 下面三个常量来至微信公众平台配置
    // 注意这里只是演示,在项目开发中请将下面的配置移到配置文件中
    const TOKEN     = 'WXAPISECKEY'; // token值自定义,必须和公众平台的设置一致
    const APPID     = 'wxba91e8941ab86e36';
    const APPSECRET = '6ccc34fe540294d487b4d115272dfbf9';

    public function __construct() {
        if (!session_id()) {
            session_start();
        }

        parent::__construct();
    }

    /**
     * 获取全局TOKEN
     * @return mixed
     */
    public function getAccessToken() {
        $access_token_cache = $this->getCache('access_token');

        if(!$access_token_cache)
        {
            $url    = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.self::APPID.'&secret='.self::APPSECRET;
            $result = json_decode($this->http_request($url), true);

            $access_token = $result['access_token'];
            $this->setCache('access_token', $access_token, $result['expires_in']);
        } else {
            $access_token = $access_token_cache['value'];
        }

        return $access_token;
    }

    public function index() {
        $signPackage = $this->getSignPackage();

        $this->display('wx.html', [
            "appId"     => self::APPID,
            "nonceStr"  => $signPackage['nonceStr'],
            "timestamp" => $signPackage['timestamp'],
            "signature" => $signPackage['signature']
        ]);
    }

    /**
     * 生成签名
     * @return array
     */
    public function getSignPackage() {
        $jsapiTicket = $this->getJsApiTicket();

        // 注意 URL 一定要动态获取
        $protocol  = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
        $url       = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
        $timestamp = time();
        // 生成随机字符
        $nonceStr  = $this->createNonceStr();

        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string    = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
        $signature = sha1($string);

        return [
            "appId"     => self::APPID,
            "nonceStr"  => $nonceStr,
            "timestamp" => $timestamp,
            "url"       => $url,
            "signature" => $signature,
            "rawString" => $string
        ];;
    }

    /**
     * 获取临时票据
     * @return mixed
     */
    private function getJsApiTicket() {
        $ticketCache  = $this->getCache('ticket');

        if (!$ticketCache) {
            $token  = $this->getAccessToken();
            $url    = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$token.'&type=jsapi';
            $result = json_decode($this->http_request($url), true);

            $ticket = $result['ticket'];
            $this->setCache('ticket', $ticket, $result['expires_in']);
        } else {
            $ticket = $ticketCache['value'];
        }

        return $ticket;
    }

    /**
     * 生成随机字符串
     * @param int $length
     * @return string
     */
    private function createNonceStr($length = 16) {
        $str   = "";
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }

        return $str;
    }

    /**
     * 获取缓存数据
     * @param $cacheKey
     * @return bool
     */
    private function getCache($cacheKey) {
        if (isset($_SESSION[$cacheKey])) {
            return ($_SESSION[$cacheKey]['expire'] > time()) ? $_SESSION[$cacheKey] : false;
        } else {
            return false;
        }
    }

    /**
     * 设置缓存
     * @param $cacheKey
     * @param $value
     * @param $expire
     */
    private function setCache($cacheKey, $value, $expire) {
        $_SESSION[$cacheKey] = [
            'value'  => $value,
            'expire' => time() + $expire
        ];
    }

    /**
     * 发起请求
     * @param $url
     * @param null $data
     * @return mixed
     */
    private function http_request($url, $data = null) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);

        if (!empty($data))
        {
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            curl_setopt($curl, CURLOPT_HTTPHEADER, array(
                    'Content-Type: application/json',
                    'Content-Length: ' . strlen($data))
            );
        }

        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }
}

10.png