微信网页登录(Vue,hash模式路由)

3,257 阅读2分钟

前提说明

不想看说明可以略过这节跳到后面看代码

我们的要跳转的网址是放在微信那一串的 URL 中,如果你之前做过微信登录就知道我说的是什么,大概类似这样

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd00cbfc8e872c336&redirect_uri=http://xxx.yuming.com/path/&response_type=code&scope=snsapi_userinfo&state=123&connect_redirect=1#wechat_redirect

其中我们要放的重点是 redirect_uri=http://xxx.yuming.com/path/ 如果你的路由模式是 mode: 'history',那么你还需要后端支持设置处理刷新和空路由处理的 404 页面,由于种种原因,后端无法对此做支持时,我们就用 mode:'hash' 路由,hash 路由是有 /#/ 来分隔,但是微信内部是不认识你的 hash,上面的一长串链接跳转的过程中,你的 URL 会被送到微信处理之后给你返回,返回来的时候会变成 http://xxx.yuming.com/path/?code=xxxxx#/,可以看到这个时候你的 /#/ 不是紧跟着你的 path 了,至于为什么会这样,这里不详细讨论,这个时候我们需要修复一下这个 url

修复 hash URL

// 如果你们是没有 path 的,就把你们的通用域名 例如 com 传进去
function fixHashUrlAndJump(pathname) {
  if (location.href.includes(`${pathname}/?code`)) {
    let href = location.href
    let url = href.substring(0, href.length - 2)
    let jingPosit = url.indexOf(`${pathname}/`) + pathname.length + 1
    let urlLeft = url.substring(0, jingPosit)
    let urlRight = url.substring(jingPosit, url.length)
    location.href = urlLeft + "#/" + urlRight
    return true
  } else {
    return false
  }
}

登录逻辑

// 本人习惯在 App.vue 下做登录操作以便有可能在生命周期时访问 Vue 的 data 数据或其他操作

import querystring from "querystring"
// 获取请求参数
function getHashParams(url) {
  return querystring.parse(url.split("?")[1] || "{}")
}
// 修复 hash 路由 url
function fixHashUrlAndJump(pathname) {
  if (location.href.includes(`${pathname}/?code`)) {
    let href = location.href
    let url = href.substring(0, href.length - 2)
    let jingPosit = url.indexOf(`${pathname}/`) + pathname.length + 1
    let urlLeft = url.substring(0, jingPosit)
    let urlRight = url.substring(jingPosit, url.length)
    location.href = urlLeft + "#/" + urlRight
    return true
  } else {
    return false
  }
}
export default {
    name: 'App',
    methods: {
        login() {
            return new Promise((resolve, reject) => {
                // 第一步 如果在你 url 经过微信端处理带回来的时候 url 已经是乱的,那么直接在这里判断一下需不需要做处理
                if (fixHashUrlAndJump("path")) return
                
                // 如果有 code 取出,没有则值为 undefined
                let code = getHashParams(location.href).code
                
                // 做一下 sessionStorage 存储,页面刷新直接从你的 sessionStorage 里面取回来
                if (sessionStorage.getItem("somedata")) {
                    // 取出存储至 Vuex 方便调用
                    this.$store.commit('setUser',{...})
                }
                
                // 如果没有 code 就转跳链接给微信处理 返回 带 code 的 url
                if (!code) {
                  return (location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd00cbfc8e872c336&redirect_uri=http://xxx.yuming.com/path/&response_type=code&scope=snsapi_userinfo&state=123&connect_redirect=1#wechat_redirect`)
                }
                
                // 如果执行到这里也说明 code 有了,还未登陆就直接登录处理了
                this.$post('xxxxx/login', {code}).then(res => { resolve(res)} )
            })
        }
    }
}