H5接入微信JS-SDK的心得

1.上源码(内含腾讯地图定位和微信定位)

/*
 * @Description: 地图定位
 * @Autor: 徐北枳
 * @Date: 2021-12-18 15:47:42
 * @LastEditors: 徐北枳
 * @LastEditTime: 2022-05-20 14:09:36
 */
import { loadJs } from '@ideacome/foundation/utils'
import { store } from 'utils';
import { authSignature } from 'api';

const txMapJS="https://mapapi.qq.com/web/mapComponents/geoLocation/v/geolocation.min.js"
const WX_JS_SDK = '//res.wx.qq.com/open/js/jweixin-1.6.0.js';
const wxApiList = ['getLocation']
let wxSign = false;

export function getLocation(callback:Function) {
    const ua = navigator.userAgent.toLowerCase();
    const isWeixin = ua.indexOf('micromessenger') != -1;
    if (!isWeixin) {
        getQQLocation(callback)
    }
    else {
        if(wxSign) {
            getWxLocation(callback)
        }
        else {
            wxInit(callback)
        }
    }
}
function getQQLocation(callback:Function) {
    loadJs(txMapJS, (res)=>{
        console.log('res', res)
        let geolocation = new window.qq.maps.Geolocation("LCLBZ-GUULK-SYUJB-AVVTB-SCYF2-PIBHF", "czh");
        geolocation.getLocation((loc:any)=>{
            console.log('success', loc)
            callback(loc)
        },
        (err:any)=>{
            console.log('fail', err)
            callback()
        }
    )
    })
}
function getWxLocation(callback:Function) {
    window.wx.getLocation({
        type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
        success: (res)=> {
            console.log('微信定位调用成功,回调数据:',res)
            const { latitude, longitude } = res
            const params = {
                lng: longitude,
                lat: latitude
            }
            callback(params)
        },
        fail: (err)=> {
            console.log(err)
            callback()
        }
    });
}
function wxInit(callback:Function) {
    const wxType = store('wxType') || 'wxbsb';
    // 进行签名的时候  Android 不用使用之前的链接, ios 需要
    const signLink =  /(Android)/i.test(navigator.userAgent) ? location.href.split('#')[0] : window.entryUrl;
    authSignature({
        url: signLink,
        wxType
    }).then(res => {
        const {data} = res
        loadJs(WX_JS_SDK, function() {
            window.wx.config({
                debug: false,
                appId: String(data.appId),
                timestamp: String(data.timestamp),
                nonceStr: String(data.nonceStr),
                signature: String(data.signature),
                jsApiList: wxApiList
            });
            window.wx.ready(function() {
                wxSign = true;
                getWxLocation(callback)
            })
        });
    }).catch((err)=>{
        wxSign = false;
    })
}

2.获取签名阶段出现的问题

  • 如果H5进入后页面路由使用了replace方法,需对IOS进行特殊处理

signLink为签名接口所需的url

// 进行签名的时候  Android 不用使用之前的链接, ios 需要
const signLink =  /(Android)/i.test(navigator.userAgent) ? location.href.split('#')[0] : window.entryUrl;

在路由replace前记录地址

// 记录进入app时的url
if (typeof window.entryUrl === 'undefined' || window.entryUrl === '') {
	window.entryUrl = location.href.split('#')[0]
}
  • 需对发送的url进行encodeURIComponent编码
  • 如果使用的是axios,默认会进行encodeURI编码,请在拦截器中把默认的encodeURI编码换成encodeURIComponent编码;
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    let url = config.url||''
    // get参数编码 把默认的encodeURI换成encodeURIComponent
    if (config.method === 'get' && config.params) {
      url += '?'
      let keys = Object.keys(config.params)
      for (let key of keys) {
        url += `${key}=${encodeURIComponent(config.params[key])}&`
      }
      url = url.substring(0, url.length - 1)
      config.params = {}
    }
    config.url = url
    return config;
  });