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;
});