乐趣区

微信公众号网页开发

基本配置

1. 设置—公众号设置—功能设置—配置 JS 接口安全域名


安全域名配置规则如下

2. 开发—基本配置


开发者密码第一次使用需要重新设置
记录 开发者 ID(AppID) 开发者密码(AppSecret)后面会用到

3.IP 白名单配置

推荐填写当前本地开发 IP 地址和服务器 IP 地址
本地开发地址获取方式

服务器 IP 地址(根据自己的服务器 Ip 地址自行填写)
多个 IP 地址填写用回车隔开

4 重要的一步

在:微信公众号 - 开发 - 接口权限查看想要调用的开发接口是否可用
如果有相关接口权限无法开启,推荐使用:微信公众平台 - 开发 - 开发者工具 - 公众平台测试帐号开发

开始开发

1. 引入 JS 文件

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

2 通过 config 接口注入权限验证配置(最重要的一步)

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

appID(前面在微信公众号基本配置中已经拿到了)
jsApiList:[‘uploadImage’,’updateAppMessageShareData’] (例:上传图片接口, 和自定义分享接口)

签名算法(微信官方提供)
jsapi_ticket
生成签名之前必须先了解一下 jsapi_ticket,jsapi_ticket 是公众号用于调用微信 JS 接口的临时票据。正常情况下,jsapi_ticket 的有效期为 7200 秒,通过 access_token 来获取。由于获取 jsapi_ticket 的 api 调用次数非常有限,频繁刷新 jsapi_ticket 会导致 api 调用受限,影响自身业务,开发者必须在自己的服务全局缓存 jsapi_ticket。

  1. 参考以下文档获取 access_token(有效期 7200 秒,开发者必须在自己的服务全局缓存 access_token):https://developers.weixin.qq….
  2. 用第一步拿到的 access_token 采用 http GET 方式请求获得 jsapi_ticket(有效期 7200 秒,开发者必须在自己的服务全局缓存 jsapi_ticket):https://api.weixin.qq.com/cgi…

2.1 签名获取拆解

第一步 GET 请求 access_token

access_token 的有效期为 7200 秒(不必反复请求)
https://api.weixin.qq.com/cgi…

  • grant_type 是获取 access_token 填写 client_credential
  • appid 是第三方用户唯一凭证
  • secret 是第三方用户唯一凭证密钥,即 appsecret**

appid 和 secret 在前面的基本配置中其实都已经拿到。但是由于开发者密码(AppSecret)是校验公众号开发者身份的密码,具有极高的安全性。不能直接暴露在前端代码中,所以 access_token 的请求需在后端完成,这里签名的生成过程都在后端完成。


当前以 node 搭建后端服务
// 获取到 access_token 示例
var url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`;
        request(url, function (error, response, body) {if (!error && response.statusCode == 200) {console.log("access_token 值" +JSON.parse(body).access_token)
            }
        });
第二步 GET 请求 jsapi_ticket

jsapi_ticket 的有效期为 7200 秒(不必反复请求)
https://api.weixin.qq.com/cgi…
用第一步获取到的 access_token 的值进行请求

//
var url = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`
        request(url, function (error, response, body) {if (!error && response.statusCode == 200) {console.log("jsapi_ticket 值" + JSON.parse(body).ticket);
            }
        });
第三步生成算法签名

const timestamp = parseInt(Date.now() / 1000) // 生成签名的时间戳
const nonceStr = Math.random().toString(36).substr(2, 15) // 生成签名的随机串
let jsapi_ticket // 在第二步生成
let url// 签名用的 url 必须是调用 JS 接口页面的完整 URL(前端请求服务端接口带入)


const sha1 = require('sha1')// 这里需要引入一个插件 npm install sha1

router.get('/', (req, res, next) => {const url = decodeURIComponent(req.query.url)// 这里的 url 采用前端加密,后端解密的形式获取
const timestamp = parseInt(Date.now() / 1000)
const nonceStr = Math.random().toString(36).substr(2, 15)
let jsapi_ticket = "在第二步拿到了"

const params = {
        nonceStr,
        jsapi_ticket,
        timestamp,
        url
    }
    const string = Object.keys(params).sort().map(key => `${key.toLowerCase()}=${params[key]}`).join('&')
    const signature = sha1(string)// 生成的签名
    
    res.status(200).json({// 将参数返回给前端
        timestamp,
        signature,
        nonceStr
    });
    
    })


module.exports = router;
    

3 前端静态页面实际调用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    
    <h1> 分享页面 </h1>
    <script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
    <script type="text/javascript" src="js/jquery-2.1.1.min.js"></script>
    <script>
    function wxFN(){
        $.ajax({
                type: "get",
                url: `http://*************/api/wx?url=${encodeURIComponent(location.href.split('#')[0])}`,
                success: function(data) {console.log(data);
                    wx.config({
                        debug: true, // 开启调试模式, 调用的所有 api 的返回值会在客户端 alert 出来,若要查看传入的参数,可以在 pc 端打开,参数信息会通过 log 打出,仅在 pc 端时才会打印。appId: data.appId, // 必填,公众号的唯一标识
                        timestamp: data.timestamp, // 必填,生成签名的时间戳
                        nonceStr: data.nonceStr, // 必填,生成签名的随机串
                        signature: data.signature, // 必填,签名
                        jsApiList: ['updateAppMessageShareData'] // 必填,需要使用的 JS 接口列表
                    });


                }
            });
    }
        wxFN()
        wx.ready(function() { // 需在用户可能点击分享按钮前就先调用
            wx.updateAppMessageShareData({
                title: '', // 分享标题
                desc: '', // 分享描述
                link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号 JS 安全域名一致
                imgUrl: '', // 分享图标
                success: function() {alert("成功")
                    // 设置成功
                }
            })
        });
        
        wx.error(function(res) {console.log('err', res)

        });
    </script>
    
</body>
</html>

4 常见错误及解决方法(微信提供)

调用 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. 确认 config 中 nonceStr(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_token 和 jsapi_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 备案数据同步有一天延迟,所以请在第二日绑定
退出移动版