微信小程序内嵌webView访问H5界面,在H5界面获取定位

一只大菜鸟J 2024-06-23 15:33:02 阅读 73

以下为uniapp代码!!!

第一步:

微信小程序webview组件路径写花生壳映射的https://***域名。

webView页面<template><view><web-view :src="wvUrl"></web-view></view></template><script>export default {data() {return {wvUrl: `https://******/h5/index/#/pages/login/login?platformToken=123456`,}},methods: {}}</script><style></style>

第二步:

 花生壳配置映射,获取域名。

花生壳动态域名解析服务-贝锐官网|花生壳官网|DNS内网穿透|域名注册|向日葵远程控制|远程桌面|蒲公英路由器-贝锐官网

icon-default.png?t=N7T8

https://www.oray.com/

 

第三步:

uniapp获取定位。(过程全前端实现无后端)

        3.1    下载所需文件(npm install crypto-js为了SHA1加密,npm install weixin-js-sdk为了使用微信的api)
        3.2    manifest.json配置

        重要:uniapp H5端口不能使用默认80(自己踩的坑)

manifest.json/* 小程序特有相关 */"mp-weixin": {"appid": "","setting": {"urlCheck": false},"usingComponents": true,"permission": {"scope.userLocation": {"desc": "您的位置信息将用于小程序位置接口的效果展示"}},// 微信小程序使用位置相关api需要在此处注册"requiredPrivateInfos": ["getLocation"]},"h5": {"devServer": {"port": 8081, // 此处代理是为了前端获取access_token、jsapi_ticket,如果是后端获取就不必写了"disableHostCheck": true,"proxy": {"/api": {"target": "https://api.weixin.qq.com","changeOrigin": true,"pathRewrite": {"^/api": "" }}}}}

        3.3    获取access_token、jsapi_ticket、签名,配置。(配置一次即可,其他页面只需要调用定位)

App.vue<script>import wx from 'weixin-js-sdk';import {appid,secret} from "@/request/secret_appid.js";import {apiGetAccessToken,apiGetJsapi_ticket,getSignature} from '@/request/locationApi.js';export default {onLaunch: function() {let {accessToken,dateTime} = uni.getStorageSync("access_token");let {jsapiTicket} = uni.getStorageSync("jsapi_ticket");let chaTime = new Date().getTime() - dateTime;let h_2 = 2 * 60 * 60 * 1000; // 2*60*60*10002小时毫秒值if (!uni.getStorageSync("access_token") || chaTime >= h_2) { // 超过2小时需要重新获取accessTokenconsole.log("重新请求token");this.gettoken();} else {console.log("直接走配置");let result = getSignature(jsapiTicket); // 传入ticket获得timestamp,nonceStr,signaturethis.configWx(result); // 初始化配置}},onShow: function() {},onHide: function() {},methods: {// 获取tokengettoken() {apiGetAccessToken(appid, secret).then(res => {// 需要缓存tokenif (!res.data.errcode) {let access_token = {accessToken: res.data.access_token,dateTime: new Date().getTime(),}uni.setStorageSync("access_token", access_token);this.getJsapi_ticket(res.data.access_token); // 获取jsapi_ticket} else {uni.showToast({title: `获取accessToken失败,errcode:${res.data.errcode}`,icon: "none"})}})},// 获取jsapi_ticketgetJsapi_ticket(accessToken) {apiGetJsapi_ticket(accessToken).then(res => {if (res.data.errcode == 0) {let jsapi_ticket = {jsapiTicket: res.data.ticket}uni.setStorageSync("jsapi_ticket", jsapi_ticket);let result = getSignature(res.data.ticket); // 签名获取timestamp,nonceStr,signaturethis.configWx(result); // 初始化配置} else {uni.showToast({title: `获取jsapi_ticket失败,errcode:${res.data.errcode}`,icon: "none"})}})},// 初始化配置configWx(result) {wx.config({debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。appId: appid, // 必填,公众号的唯一标识timestamp: result.timestamp, // 必填,生成签名的时间戳nonceStr: result.noncestr, // 必填,生成签名的随机串signature: result.signature, // 必填,签名jsApiList: ["getLocation"] // 必填,需要使用的JS接口列表});wx.error((err) => {uni.showToast({title: "配置失败",icon: "none"})})},}}</script><style></style>

        3.4    获取定位方法

weixin-js-sdk_location.jsimport wx from 'weixin-js-sdk';// 坐标转化的方法import {gcj02tobd09} from '@/utils/coordinateTransform.js';// 获取地理坐标export function getByLocation() {return new Promise((resolve, reject) => {wx.ready(() => {wx.getLocation({type: 'gcj02', // 默认为wgs84(gcj02)的gps坐标success: function(res) {let result = gcj02tobd09(res.longitude, res.latitude);let lngLat = {code: 200,lng: result[0],lat: result[1]};resolve(lngLat)},error: function(err) {reject(err)},})})})}

        3.5    使用

<template><view></view></template><script>import {getByLocation} from '@/utils/weixin-js-sdk_location.js';export default {data() {return {}},onShow() {// 通过公众号sdk获取位置getByLocation().then(res => {if (res.code == 200) {alert(JSON.stringify(res))} else {uni.showToast({title: "获取经纬度失败",icon: "none"})}})},methods: {}}</script><style></style>

第四步:所需文件

        4.1    secret_appid.js:存储appid及secret

// 测试公众号let appid = "";let secret = "";export {appid,secret}

        4.2    locationApi.js:获取accessToken、jsapi_ticket、签名等方法

import CryptoJS from "crypto-js";/* 请求函数*/function request({url,method,params}) {uni.showLoading({title: "加载中..."});return new Promise((resolve, reject) => {uni.request({url: url,method: method || 'GET',data: params || {},success(res) {resolve(res);},fail(err) {reject(err);},complete() {uni.hideLoading();}});});}/* 第一步:获取accessTokenaccess_token的有效期目前为2个小时,需定时刷新传参:appid:开发者ID(AppID)secret:开发者密码(AppSecret)*/// https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}function apiGetAccessToken(appid, secret) {return request({url: `/api/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`,})}/* 第二步:获取jsapi_ticketjsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket)用于权限验证的签名传参:access_token*/function apiGetJsapi_ticket(access_token) {return request({url: `/api/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`,})}// 第三步:获取signaturefunction getSignature(ticket) {let noncestr = getRandomString(); // 16位随机字符串let jsapi_ticket = ticket; // 此处必须得到有效的jsapi_ticketlet timestamp = getTimestamp(); // 时间戳let url = getConfigUrl(); // URLlet obj = {noncestr,jsapi_ticket,timestamp,url}let string1 = sort_ascii(obj);let signature = CryptoJS.SHA1(string1).toString();let result = {noncestr,timestamp,signature}return result;}/* 签名算法所需参数:noncestr:随机字符串,jsapi_ticket:有效的,timestamp:时间戳,url:(当前网页的URL,不包含#及其后面部分)对以上四个参数整理成对象并按ascii码从小到大排序,排完序在进行sh1加密得到signaturelet result = { noncestr, jsapi_ticket: ticket, timestamp, url: getConfigUrl() };sort_ascii(result)*/// 生成一个随机的字符串function getRandomString(len = 16) {let chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890';let maxPos = chars.length;let character = '';if (len) {for (let i = 0; i < len; i++) {character += chars.charAt(Math.floor(Math.random() * maxPos))}} else {for (let i = 0; i < len; i++) {character += chars.charAt(Math.floor(Math.random() * maxPos))}}return character;}// 获取时间戳function getTimestamp() {return new Date().getTime();}// 获取urlfunction getConfigUrl() {let u = window.navigator.userAgent;let isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端//安卓需要使用当前URL进行微信API注册(即当场调用location.href.split('#')[0])//iOS需要使用进入页面的初始URL进行注册,(即在任何pushstate发生前,调用location.href.split('#')[0])let url = '';if (isiOS) {url = `${window.localStorage.getItem('_iosWXConfig_') || window.location.href.split('#')[0]}`; //获取初始化的url相关参数} else {url = window.location.href.split('#')[0];}return url;}// 按ascii码从小到大排序function sort_ascii(obj) {let arr = [];let num = 0;for (let i in obj) {arr[num] = i;num++;}let sortArr = arr.sort();let str = ''; //自定义排序字符串for (let i in sortArr) {str += sortArr[i] + '=' + obj[sortArr[i]] + '&';}//去除两侧字符串let char = '&';str = str.replace(new RegExp('^\\' + char + '+|\\' + char + '+$', 'g'), '');return str;}export {apiGetAccessToken,apiGetJsapi_ticket,getRandomString,getTimestamp,getConfigUrl,sort_ascii,getSignature}

        4.3    weixin-js-sdk_location.js:获取定位封装的方法

import wx from 'weixin-js-sdk';import {gcj02tobd09} from '@/utils/coordinateTransform.js';// 获取地理坐标export function getByLocation() {return new Promise((resolve, reject) => {wx.ready(() => {wx.getLocation({type: 'gcj02', // 默认为wgs84(gcj02)的gps坐标success: function(res) {let result = gcj02tobd09(res.longitude, res.latitude);let lngLat = {code: 200,lng: result[0],lat: result[1]};resolve(lngLat)},error: function(err) {reject(err)},})})})}

        4.4    coordinateTransform.js:坐标转换方法

// 地图坐标转换公共方法//定义一些常量const PI = 3.1415926535897932384626;const a = 6378245.0;const ee = 0.00669342162296594323;export function transformlat(lng, lat) { var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng)); ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0; ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0; return ret}export function transformlng(lng, lat) { var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng)); ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0; ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0; ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0; return ret}/** * 判断是否在国内,不在国内则不做偏移 * @param lng * @param lat * @returns {boolean} */export function out_of_china(lng, lat) { return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);}/** * WGS84转GCj02 * @param lng * @param lat * @returns {*[]} */export function wgs84togcj02 (lng, lat) { if (out_of_china(lng, lat)) { return [lng, lat] } else { var dlat = transformlat(lng - 105.0, lat - 35.0); var dlng = transformlng(lng - 105.0, lat - 35.0); var radlat = lat / 180.0 * PI; var magic = Math.sin(radlat); magic = 1 - ee * magic * magic; var sqrtmagic = Math.sqrt(magic); dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); var mglat = lat + dlat; var mglng = lng + dlng; return [mglng, mglat] }}/** * GCJ02 转换为 WGS84 * @param lng * @param lat * @returns {*[]} */export function gcj02towgs84 (lng, lat) { if (out_of_china(lng, lat)) { return [lng, lat] } else { var dlat = transformlat(lng - 105.0, lat - 35.0); var dlng = transformlng(lng - 105.0, lat - 35.0); var radlat = lat / 180.0 * PI; var magic = Math.sin(radlat); magic = 1 - ee * magic * magic; var sqrtmagic = Math.sqrt(magic); dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI); dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI); let mglat = lat + dlat; let mglng = lng + dlng; return [lng * 2 - mglng, lat * 2 - mglat] }}/** * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换 * 即 百度 转 谷歌、高德 * @param bd_lon * @param bd_lat * @returns {*[]} */export function bd09togcj02 (bd_lon, bd_lat) { var x_pi = 3.14159265358979324 * 3000.0 / 180.0; var x = bd_lon - 0.0065; var y = bd_lat - 0.006; var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi); var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi); var gg_lng = z * Math.cos(theta); var gg_lat = z * Math.sin(theta); return [gg_lng, gg_lat]}/** * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换 * 即谷歌、高德 转 百度 * @param lng * @param lat * @returns {*[]} */export function gcj02tobd09 (lng, lat) { var x_PI = 3.14159265358979324 * 3000.0 / 180.0; var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI); var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI); var bd_lng = z * Math.cos(theta) + 0.0065; var bd_lat = z * Math.sin(theta) + 0.006; return [bd_lng, bd_lat]}/** * WGS84转BD09 * @param lng * @param lat * @returns {*[]} */export function WGS84ToBD09 (lng, lat) { let gcj02 = wgs84togcj02(lng, lat); return gcj02tobd09(gcj02[0], gcj02[1]);}/** * BD09转WGS84 * @param lng * @param lat * @returns {*[]} */export function BD09ToWGS84 (lng, lat) { let gcj02 = bd09togcj02(lng, lat); return gcj02towgs84(gcj02[0], gcj02[1]);}

第五步:

测试公众号(开启获取位置的权限、js接口安全域名)

微信公众平台

icon-default.png?t=N7T8

https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

第六步:

vebniew的src域名要和js接口安全域名一致 (不能一个写花生壳域名一个写本地ip)



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。