微信公众号开发踩坑集锦

4,151 阅读3分钟
原文链接: zhuanlan.zhihu.com
目的

最近半年多一直在公众号上开发业务, 由于第一次开发公众号所以踩了很多坑, 因此写这篇文章一是为了总结, 而是没准对那些即将踩坑的童鞋或者踩坑中的童鞋有点帮助.

交代背景

基于Vue开发的单页应用, 路由hash模式.

开发前准备工作
  • 申请公众号, 开通各种需要的权限.
  • 设置页面授权域名
  • 设置JS接口安全域名
  • 绑定开发者微信
  • 下载开发者工具
  • 利用开发者工具本地调试微信sdk
// 方案很多, 这里只介绍我们用的方法
- 安装nginx, 设置配置文件. 思路就是监听80端口, 转向我们本地项目.

server {
    listen 80;
    server_name localhost;

    location / {    
      index  index.html index.htm home.html;
      proxy_pass http://localhost:9999/; 
     }
   }
- 然后在你的hosts,设置你的域名指向本地. 推荐SwitchHosts!.
微信授权

微信文档已经很详细了。

微信公众平台
授权方式:
1. 静默授权: 以snsapi_base为scope发起的网页授权。
2. 用户手动触发的以snsapi_userinfo为scope发起的网页授权。获取的信息权限更多。

由于我们业务上支持游客模式与用户模式: 所有我们需要在任意页面通过业务需要触发用户模式进行授权并返回当前页或者登陆页面(即新用户).

自定义分享

由于微信默认的分享或暴露出外链, 所有我们需要对每个页面进行自定义一次.

  • 绑定域名
  • 引入js文件
我开发时候发现没有1.4.0版本的包, 所有就自己发了一个在npm, 有需要的也可以安装.
https://www.npmjs.com/package/easy-wechat-js-sdk
  • 通过config接口注入权限验证配置
- 一般都是前端用url(location.href.split('#')[0])调用后台接口去签名。
- url需要进行encodeURIComponent进行编码.
- 同一个url仅需调用一次签名
- 对于变化url的SPA的web app可在每次url变化时进行调用,所以你可以在App.vue里面监听$route变化去开始签名
  • 开始调用微信分享sdk方法

这里有几个需要注意.

  1. 自定义分享成功后的页面url会带有微信返回的参数, 因此再你分享后的帖子再次二次分享时候, 如果你没考虑到的话, 二次分享就会失败, 因此最好就是使用当前页面去签名以及作为分享的link.
对于IOS系统会自动增加如下参数:

朋友圈 from=timeline&isappinstalled=0
微信群 from=groupmessage&isappinstalled=0
好友分享 from=singlemessage&isappinstalled=0

对于安卓系统会自动添加如下参数:

朋友圈 from=timeline
微信群 from=groupmessage
好友分享 from=singlemessage

2. 安卓手机下自定义分享后会截掉你#之后的所有内容. 由于我们使用的是hash模式, 因此会有这样的bug, 这就导致二次分享时候一直只会进入首页, 显然这个在业务上是不允许的.

解决方法:

// 针对安卓系统, 需要特殊处理添加一个wx-share.html文件作为中转.处理分享的link.
if (platform === 'Android') {
                // fix安卓下的自定义分享
                realLink = window.location.origin + window.location.pathname + 'wx-share.html?redirect=' + encodeURIComponent(window.location.href)
            }

在wx-share.html里面就是直接重定向到我们之前分享的页面.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title></title>
</head>

<body>
    <script type="text/javascript">
    function getParmas(url) {
        var theRequest = {},
            strs;
        if (url.indexOf('?') != -1) {
            var str = url.split('?')[1];
            strs = str.split("&");
            for (var i = strs.length - 1; i >= 0; i--) {
                theRequest[strs[i].split("=")[0]] = strs[i].split("=")[1];
            }
        }
        return theRequest;
    };
    var parms = getParmas(window.location.href);
    window.location.href = decodeURIComponent(parms.redirect);

    </script>
</body>

</html>
微信支付

支付的话提示还好. 就是需要注意在商户配置支付目录问题:

1. 需要配置一个在你项目的根目录
2. 配置到具体你的支付页面
在公众号通过浏览器打开任意界面只会进入首页问题

业务需要: 微信端我们有一个app下载引导页, 也就是为例

在任意页面你去复制链接或者通过浏览器打开等都会发现只进入首页, 这是由于x5内核就会出现pushstate问题, 在X5里,url栏不会改变.

解决方法:

// loadApp页面: 引导页
 
// hash模式监听的是hashChange
const loadAppUrl = `${location.origin}${location.pathname}?v=2018#/loadApp?${location.hash.split('?')[1]}`
const state = {
  title: "下载App",
  url: loadAppUrl
};
window.history.pushState(state, state.title, state.url);
window.location.href = loadAppUrl;
// 先跳转url再绑定事件顺序不能反
window.addEventListener("popstate", this.handleGoBack, false);

这样子问题解决了, 但是会导致一个问题就是进入loadApp页面后, 我点击后退需要后退两次, 这显然用户体验不好.

所以我想到一个hack方法.

// 之所以需要手动pushState一次是因为进入loadApp也会触发popstate
const state = {
   title: "下载App",
   url: loadAppUrl
 };
window.history.pushState(state, state.title, state.url);
// 然后监听popstate事件, 一旦用户点击物理后退按钮就往后退
window.addEventListener("popstate", this.handleGoBack, false);
  handleGoBack () {
     this.$router.go(-1)
  },
// 组件销毁时候需要解绑事件
window.removeEventListener("popstate", this.handleGoBack)
在微信端下唤起本地App

起始思路也比较简单:

  1. 首先微信设置有白名单, 我们在微信里面直接是拉不起App的.

2. 只能引导用户用浏览器打开App下载页面。

3. 与安卓端/IOS端约定Schema协议, 如果本地安卓会拉起App,没有就跳转到AppStore或者腾讯应用宝去下载.

具体思路可以参考这篇文章总结的很好, 我们的做法与他的类似,这里就不贴代码了.

H5唤起APP指南(附开源唤端库) - 掘金

总之: 微信下公众号坑真多!