此文章中实例用测试号进行演示 。getLocation
openLocation
主要运用微信JS-SDK,微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
微信网页开发JS-SDK说明文档
使用
1、首先公众号中需要配置JS接口安全域名
注意:域名不能添加 http
或 https
2、配置支持环境
1)引入JS文件,在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js
如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)
。
2)或引入 weixin-jsapi'
import wx from 'weixin-jsapi'
3、设置 config 接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用。通过 wx.config
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});
config 接口中所需参数,示例中是从后台获取的。
const url = window.location.href.split('#')[0] // 当前界面的地址,取#之前的;url域名必须与之前设置的JS接口安全域名一致
this.$http({
url: this.$http.adornUrl(this.$store.state.urlCommon + '/createJsapiSignature'),
method: 'get',
params: this.$http.adornParams({url: url})
}).then(({data}) => {
if (data.code !== 0) {
return
}
wx.config({
debug: false,
appId: data.signature.appId,
timestamp: data.signature.timestamp,
nonceStr: data.signature.nonceStr,
signature: data.signature.signature,
jsApiList: ['getLocation'] // 获取定位地址
})
})
4、通过 ready 接口处理成功验证
config
信息验证后会执行 ready
方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
wx.ready(function(){
// xxx
});
通过error接口处理失败验证
config
信息验证失败会执行 error
函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
wx.error(function(res){
// xxx
});
5、wx.getLocation 获取定位
let that = this // 为在getLLocation success 方法中使用外层this
wx.ready(() => {
wx.getLocation({
debug: false,
type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
that.latitude = parseFloat(res.latitude) // 纬度,浮点数,范围为90 ~ -90
that.longitude = parseFloat(res.longitude) // 经度,浮点数,范围为180 ~ -180。
},
fail: function (err) { // 接口调用失败时执行的回调函数。
console.log(err)
}
})
接口调用说明
所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数:
- success:接口调用成功时执行的回调函数。
- fail:接口调用失败时执行的回调函数。
- complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。
- cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。
- trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。
备注:不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。
以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下:
调用成功时:"xxx:ok"
,其中xxx为调用的接口名
用户取消时:"xxx:cancel"
,其中xxx为调用的接口名
调用失败时:其值为具体错误信息
完整实例
获取当前用户定位
import wx from 'weixin-jsapi'
this.$http({
url: this.$http.adornUrl(this.$store.state.urlCommon + '/createJsapiSignature'),
method: 'get',
params: this.$http.adornParams({url: url})
}).then(({data}) => {
if (data.code !== 0) {
return
}
wx.config({
debug: false,
appId: data.signature.appId,
timestamp: data.signature.timestamp,
nonceStr: data.signature.nonceStr,
signature: data.signature.signature,
jsApiList: ['getLocation', 'openLocation']
})
wx.ready(() => {
wx.getLocation({
debug: false,
type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
that.latitude = parseFloat(res.latitude) // 纬度,浮点数,范围为90 ~ -90
that.longitude = parseFloat(res.longitude) // 经度,浮点数,范围为180 ~ -180。
if (!that.longitude || !that.latitude) {
that.loading = false
that.$dialog.alert({
message: `维修完成前,需要获取地理位置,请确认手机定位功能已开启`,
})
return false
}
wx.openLocation({
latitude: that.latitude, // 纬度,浮点数,范围为90 ~ -90
longitude: that.longitude, // 经度,浮点数,范围为180 ~ -180。
name: '', // 位置名
address: '', // 地址详情说明
scale: 20, // 地图缩放级别,整形值,范围从1~28。默认为最大
infoUrl: '' // 点位链接
})
},
fail: function (err) {
console.log(err)
}
})
})
}).catch((err) => {
console.log(err)
})
wx.getLocation 中的 type
默认为 wgs84的gps
坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
。
经纬度转换
火星坐标(gcj02),腾讯、Google、高德通用,**百度地图(百度坐标BD-09)**有自己的坐标。若为 wgs84 ,位置回显会出现偏差。改为 gcj02 虽然微信端或者腾讯高德通用 gcj02 坐标的不会发生偏差,但是 pc 端若用百度地图,就会出现较大偏差。所以还需要解决经纬度转换。
gcj02 转为 百度地图
// 地图转换
// 参数形式为lng,lat
// 返回值:lng,lat
gcj2bdString (lng, lat) {
const xpi = 3.14159265358979324 * 3000.0 / 180.0
const z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * xpi)
const theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * xpi)
return {lng: z * Math.cos(theta) + 0.0065, lat: z * Math.sin(theta) + 0.006}
}
微信地图(gcj02)转为百度地图
参考百度地图接口文档
http://api.map.baidu.com/geoconv/v1/?coords=114.21892734521,29.575429778924&from=1&to=5&ak=你的密钥 //GET请求
所以此处我们用的是:
`http://api.map.baidu.com/geoconv/v1/?coords=${that.longitude},${that.latitude}&from=3&to=5&ak=yourAK`
跨域的解决
本地请求接口可通过设置代理处理跨域问题:
config/index.js
线上此时需要配置ngix,设置线上代理;若不想要配置代理,可用 jsonp
解决跨域
使用 jsonp
一、安装 jsonp
npm install vue-jsonp --save
二、main.js 中引入
import {VueJsonp} from 'vue-jsonp'
Vue.use(VueJsonp)
三、组件中使用(this.$jsonp(url).then())
const url = `http://api.map.baidu.com/geoconv/v1/?coords=${that.longitude},${that.latitude}&from=3&to=5&ak=yourAk`
this.$jsonp(url).then(res => {
if (res.status === 0) {
let params = {
longitude: res.result[0].x,
latitude: res.result[0].y
}
})