微信网页授权+分享踩过的坑

栏目: JavaScript · 发布时间: 7年前

内容简介:折磨我两个工作日加周末一天的问题,我觉得还是有必要记录一下,为什么程序员总是加班,就是遇到这些意想不到的问题领导:我想做两个页面,放在微信里面可以访问我:简单啊,用H5实现

背景

折磨我两个工作日加周末一天的问题,我觉得还是有必要记录一下,为什么 程序员 总是加班,就是遇到这些意想不到的问题

需求

领导:我想做两个页面,放在微信里面可以访问

我:简单啊,用H5实现

产品设计中...

产品:好了,看看没问题就开始开发吧

我:什么时候多了一个需要获取用户信息(产品总是给人惊喜不端)

没有试过微信授权这一块,首先内心三连问,能不能拒绝,能不能改需求,能不能通过熟悉的秘方实现;然而并没有什么用(笑哭表情)

开发中

业务功能没什么难点,模拟一个用户信息,很快就开发完成了...

微信网页授权

官方文档: https://mp.weixin.qq.com/wiki...

1.登录自己的服务号,查看已有的权限

微信网页授权+分享踩过的坑

注意:这里只能是服务号,订阅号没有权限,服务号只能由企业和组织申请

2.公众号设置

微信网页授权+分享踩过的坑

注意:授权回调域名配置规范为全域名,比如需要网页授权的域名为:www.qq.com,配置以后此域名下面的页面 http://www.qq.com/music.htmlhttp://www.qq.com/login.html 都可以进行OAuth2.0鉴权。但 http://pay.qq.comhttp://music.qq.comhttp://qq.com无法进行OAuth2.0...

微信网页授权+分享踩过的坑

注意:下载这个文件放在域名对应的根目录下

3.链接的生成

https://open.weixin.qq.com/co...

微信网页授权+分享踩过的坑

以访问www.qq.com/#/detail.html为例,上面第2步的网页授权域名设置成 www.qq.com

REDIRECT_URI为encodeURIComponent(' http://www.qq.com/#/detail.html ')

SCOPE为snsapi_base或snsapi_userinfo,区别是只获取用户id,还是获取更多用户信息

state随便写吧,以123为例(没有看出具体有什么用)

其它参数不变

注意:为什么要用encodeURIComponent,你想想,你在url里面直接写url,怎么能直接把它解析成参数

4.放在微信里访问

把第3步上面生成的链接,做为聊天消息,拷贝到微信里面,点击打开,此时我们用alert(location.href)就会发现,地址变成了 http://www.qq.com/?code=生成...

// 获取url参数
export function getQueryVariable(variable) {
  const query = window.location.search.substring(1)
  const vars = query.split("&")
  for (let i=0; i<vars.length; i++) {
    const pair = vars[i].split("=")
    if(pair[0] === variable) return pair[1]
  }
  return undefined
}

// 获取code的值
const code = getQueryVariable('code')

注意:code只能用一次,而且还有时间限制,code插入的位置尤其要注意,不是在

/#/ 后面,所以用vue或react的路由组件中获取路由参数方式是不可行的,老老实实的写原生js获取

5.通过code获取用户id

微信网页授权+分享踩过的坑

code获取到了以后前端就无能为力了,接下来的步骤只能交给后台了(数据安全性考虑,比如AppSecret不能暴露给前端),自古以来,前端的地位略低于后端,nodejs的出现极大的拯救了前端,虽然后面的事情前端做不了,但我们可以用nodejs或者是类似于postman这种的工具,把后面的接口模拟跑通,然后直接告诉后端,你该调什么接口,用什么参数,后端文档都不用看;当然你也可以做个小白纸,什么都抛给后端,让后端指挥你怎么做(在一个团队中,各个角色的重要性,就看 能做的 事情)

网页授权就这么搞完了,是不是很简单(笑哭表情),可以愉快的玩耍了

当我把这个链接通过微信右上角分享给同事一起测试时,啪啪打脸了...,呈现的现象

1.通过code获取用户id,报错了

2.分享标题,描述,图标好丑,我能不能改(好像没有分享这个需求,但不分享的话,用户怎么看,我要不要做,没有这个需求,我要不要把锅丢给产品,我好方,但仅有的一点点职业素养告诉我,我还是做吧,做为一个合格的程序员,必备的技能不就是脑补一些产品没想到需求吗(笑哭表情))

分析原因:

1.打印出分享的地址alert(location.href),为 http://www.qq.com/?code=上一... ,微信分享出去的是当前访问的地址(原滋原味,加了一些防腐剂,多了一个from=xxxx,应该是来源),但我理想中想要的是上面第3中的地址(重定向之前的地址),报错的原因是同一个code用了两次

解决思路:

1.自定义分享地址,此时的思路是,地址改成 https://open.weixin.qq.com/co... 这种

2.自定义标题,描述和图片

3.最终方案看下面

微信网页分享

官方文档: https://mp.weixin.qq.com/wiki...

1.还是先配置相应的权限

微信网页授权+分享踩过的坑

2.生成签名(后端做的,前端可以选择跳过)

微信网页授权+分享踩过的坑

这个时候就不得不吐槽微信的文档了,残缺了,在第一步就卡住了,只能求助网友,后面我发现

微信网页授权+分享踩过的坑

这里有,IP白名单也要设置,否则是拿不到access_token的,其它的签名怎么生成的后端照着文档做就行了

注意点:网页授权和分享是两个完全独立的模块,分享的access_token和授权返回的access_token是完全不一样的概念

3.前端配置

yarn add weixin-js-sdk

此时我的版本是"weixin-js-sdk": "^1.4.0-test", 微信客户端的版本是7.0.4,竟然遇到一个大坑

微信网页授权+分享踩过的坑

微信官方让我用最新的接口,我试了很久都没有调通,总以为是自己的姿势不对,后面实在不行了,我试了一下老接口,竟然通了,竟然通了,竟然通了,我想崩溃了

上代码

wx.config({
    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,在pc端时会打印出来,不需要的话可以将true改成false。
    appId: data.appid,  // 必填,公众号的唯一标识
    timestamp: data.timestamp,  // 必填,生成签名的时间戳
    nonceStr: data.nonceStr,  // 必填,生成签名的随机串
    signature: data.signature,  // 必填,签名
    jsApiList: ['onMenuShareAppMessage','onMenuShareTimeline','onMenuShareQQ','onMenuShareQZone']
  })

  wx.ready(function () {
    //分享到朋友圈
    wx.onMenuShareTimeline({
      title, // 分享标题
      link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
      imgUrl, // 分享图标
    })
    //分享给朋友
    wx.onMenuShareAppMessage({
      title, // 分享标题
      desc, // 分享描述
      link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
      imgUrl, // 分享图标
    })
    //分享到QQ
    wx.onMenuShareQQ({
      title, // 分享标题
      desc, // 分享描述
      link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
      imgUrl, // 分享图标
    })

    //分享到QQ空间
    wx.onMenuShareQZone({
      title, // 分享标题
      desc, // 分享描述
      link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
      imgUrl, // 分享图标
    })
  })

注意:

1.data是后台返回的签名信息

2.分享链接,该链接域名必须与当前页面对应的公众号JS安全域名一致,公众号里面配置的是www.qq.com,这里分享的地址只能是以www.qq.com开头的,和我们理想的 https://open.weixin.qq.com/co... 开头差距很大(怎么授权,好方)

如果只是单纯的自定义分享,到这里就结束了,如果既要分享又要授权,又有问题需要解决了

4.重定向

  1. 初始打开地址为: http://www.qq.com/#/detail.html ,这个时候不带code
  2. 进入页面之后。location.href = ' https://open.weixin.qq.com/co... ' (下面都称为重定向)
  3. 页面地址变成了 http://www.qq.com/?code=生成...
  4. 用的是同一个页面,所以需要判断url有没有code,来决定是否要执行第2步,否则会死循环

文章写到这里,已经解决了授权+分享,是不是感觉故事很平稳,一部好的电影怎么能这么快结束

高潮(大坑来了)

现象

微信中打开页面,用安卓的物理返回键,点一下返回不了,需要连续快速点两下才能退出

分析原因

打开的页面是不带code的地址,经过重定向后,生成了带code的地址,此时浏览器的历史记录中会有两条记录,从带code的地址返回到不带code的地址,页面判断没有带code,又会重定向到带code的页面,产生了死循环

解决方案

1.不让它产生多一条的记录

首先想到的是location.replace(url), 发现把url替换成授权的地址时( https://open.weixin.qq.com/co... ),并不会像想象中的那样工作,还是会有两条历史记录(不清楚微信为什么不解决,还是解决不了)

结果:失败

2.代码控制清除一条历史记录

const params = getQueryParams()
const code = sessionStorage.getItem('code')
if (!params.code && !code) {
  let url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${yourAppId}&redirect_uri=${encodeURIComponent(location.href)}&response_type=code&scope=snsapi_base&state=1#wechat_redirect`
   window.location.replace(url)
} else if(!code){
   sessionStorage.setItem('code', params.code)
   history.back()
}

搜索了一大圈,看见了这段代码(来自: https://www.cnblogs.com/wonyu... ),仿佛看见了光,里面比较讲究的就是

sessionStorage(只在当前会话有效),用当前会话窗口储存的code,来判断不带code的页面要不要重定向

看似很完美的代码,还是逃不过微信的大坑,通过链接进入时,偶尔会遇到页面空白

原因:

上面用到的历史记录返回,页面不刷新(偶尔),我尝试过强制微信浏览器刷新,甚至怀疑是vue的坑,然后用原生写了一段js来操作dom,并没有什么用

最后发现返回的时候,js都能正常的执行, UI不重新渲染,UI不重新渲染,UI不重新渲染 ,偶尔出现,不是必现,我再次好方

结果:偶尔失败

3.返回两次,才能退出

借鉴上面的思路,判断当前会话窗口储存的code是否有值,有值就不重定向

结果:解决了偶尔不渲染的问题和死循环的问题,但对于有轻微强迫症的我来说,需要点两次才能返回还是挺难接受的

本来属于愉快的周末,就在微信这个大坑里结束了,关上电脑,沉思一会(想想如何说服测试同学这个问题解决不了,是微信的坑(笑哭表情))

结尾

处女座最大的悲哀就是心里不能放事情,总感觉不踏实,休息也休息不好(悲哀)

突然想到前段时间开发的app,自己控制过android的返回,微信会不会也提供了自定义返回呢,经过一大堆的搜索,发现js就有能监听浏览器返回的事件(有些知识点不用,慢慢就忘了),兜兜转转了一大圈,至少用我的周末帮大家证明了网上说的很多方式行不通,哈哈哈,终极解决,上代码(vue的思路)

created () { // 当前需要直接退出的页面
    window.history.pushState(null, null, "")
    window.addEventListener("popstate", this.popstate, false)
  },
  destroyed: function () { // 记得清除,不然单页面,其它页面也可以用
    window.removeEventListener("popstate", this.popstate, false)
  },
  methods: {
    popstate () {
      wx.closeWindow() // 微信网页退出
    }
  }

注意:为什么要多window.history.pushState(null, null, "")这句代码,因为popstate只能监听pushState创建的

备注:微信的文档会更新,当你使用时(看一下这篇文章的出生时间),最好参考官方文档,如果你觉得有一点帮助了你,请点个赞(程序员写文章不容易,最烦写这种随时可能过时的文章,哈哈哈)


以上所述就是小编给大家介绍的《微信网页授权+分享踩过的坑》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Algorithmic Beauty of Plants

The Algorithmic Beauty of Plants

Przemyslaw Prusinkiewicz、Aristid Lindenmayer / Springer / 1996-4-18 / USD 99.00

Now available in an affordable softcover edition, this classic in Springer's acclaimed Virtual Laboratory series is the first comprehensive account of the computer simulation of plant development. 150......一起来看看 《The Algorithmic Beauty of Plants》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

SHA 加密
SHA 加密

SHA 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具