要实现一个如下功能:
在分享到微信的页面,怎么使用微信的接口
获取定位信息
?
1.首先需要有微信开发者账号
微信开发者平台- 进入后注册新用户
- 选择
订阅号
- 填写相关必要信息
- 完成
2.找到开发者文档
- 进入个人主页页面
- 左侧菜单的最下方
- 找到
开发者工具
- 找到
开发者文档
- 左侧菜单点击
微信网页开发
- 点击
JS-SDK 说明文档
- 即可打开 也可以省略以上步骤 直接点击下方的
JS-SDK文档
即可打开相应页面
JS-SDK文档
3.绑定域名
- 路径:
设置 - 公众号设置 - 功能设置
- 按要求设置符合要求的
JS安全域名
(注意:是域名不是URL,不需要添加http://前缀,个别域名也不需要添加www.,如果出现valid url domain
问题,八成就是JS安全域名配置得有些问题) - 配置服务器相关设置(需要将当前弹出层的XXX.txt文档放在域名或路径指向的web服务器(或虚拟主机)的目录(若填写域名,将文件放置在域名根目录下,例如wx.qq.com/MP_verify_iHHFUQfq5cxa54Wz.txt;若填写路径,将文件放置在路径目录下,例如wx.qq.com/mp/MP_verify_iHHFUQfq5cxa54Wz.txt),并确保可以访问)
4. 引入所需的JS文件
- 本次使用的是
vue-cli
构建的项目,所以在public/index.html
中添加<script>标签
将js引入页面
5.配置IP白名单
- 路径:
开发 - 基本配置 - 公众号开发信息 - IP白名单
- 可将开发者电脑的ip和服务器ip均设置上,这样可以本地开发的时候进行边测试边开发
- 此步骤是必须优先于下一步 否则下一步所需的
access_token
无法获取到
6.后台进行加密算法
- 后台代码贴在下面 主要逻辑已写注释
package com.mutou.testApi.controller;
import com.alibaba.fastjson.JSON;
import com.mutou.testApi.dto.GetTicketDto;
import com.mutou.testApi.dto.GetTokenDto;
import com.mutou.testApi.plugins.CheckEmptyUtil;
import com.mutou.testApi.plugins.RedisTemplateService;
import com.mutou.testApi.plugins.Sha1Util;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @author 杨喜存
* @since 2020/2/12 3:46 PM
*/
@RestController
@ResponseBody
@RequestMapping("/test")
public class TestController {
private String APP_ID = "your app_id";
private String SECRET = "your secret";
private String GRAND_TYPE = "client_credential";
private String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?"
+ "grant_type="+GRAND_TYPE
+ "&appid="+APP_ID
+ "&secret="+SECRET;
private String TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=";
@Resource private RedisTemplateService redisTemplateService;
@GetMapping("/get-signature")
Map<String,String> test(@RequestParam("nonceStr") String nonceStr,
@RequestParam("timestamp") String timestamp,
@RequestParam("url") String url) throws NoSuchAlgorithmException {
// springboot中使用RestTemplate代替httpClient请求
RestTemplate restTemplate = new RestTemplate();
// 缓存access_token
String token = redisTemplateService.get("token",String.class);
if(CheckEmptyUtil.isEmpty(token)){
// 发送get请求 获取access_token 并缓存
GetTokenDto resultDto = restTemplate.getForObject(TOKEN_URL, GetTokenDto.class);
token = resultDto.getAccess_token();
redisTemplateService.set("token", token, 2L, TimeUnit.HOURS);
}
// 将access_token拼接在获取ticket的接口上
TICKET_URL = TICKET_URL+ token;
// 缓存ticket
String ticket = redisTemplateService.get("ticket",String.class);
if(CheckEmptyUtil.isEmpty(ticket)){
// 发送get请求 获取ticket 并缓存
GetTicketDto getTicketDto = restTemplate.getForObject(TICKET_URL, GetTicketDto.class);
ticket = getTicketDto.getTicket();
redisTemplateService.set("ticket",ticket,2L,TimeUnit.HOURS);
}
// 按ascii升序进行排列
String str1 =
"jsapi_ticket="+ticket
+ "&noncestr="+nonceStr
+ "×tamp="+timestamp
+ "&url="+url;
System.out.println("jsapi_ticket:"+ticket);
System.out.println("timestamp:"+timestamp);
System.out.println("url:"+url);
// 进行sha1加密
String sha1Str = Sha1Util.getSha1(str1.getBytes());
System.out.println(sha1Str);
Map<String,String> result = new HashMap<>();
result.put("url",url);
result.put("token",token);
result.put("jsapi_ticket",ticket);
result.put("signature",sha1Str); // 主要 其他的返回值只是为了测试用
// 返回
return result;
}
}
7. 前端代码
- 此次测试前端只是简单发送了一次get请求 得到上面后台的
signature
,将其配置到wx.config
中,只有我们加密后的signature
和微信方加密后的signature
一致,此时wx.config
才算成功,后续操作才可顺利完成,wx.config
是第一步。
<template>
<div>
<a @click="onShareClick">点击分享</a>
</div>
</template>
<script>
export default {
name: "TestShare",
mounted() {
this.getSignature()
},
methods: {
getSignature() {
// 时间戳
let timestamp = (new Date()).valueOf();
timestamp = String(timestamp).substr(0,String(timestamp).length-3)
// 随机字符串
let nonceStr = timestamp;
// url - 地址栏中的#前的url
let url = encodeURIComponent(location.href.split('#')[0])
// 全部参数
let param = `?timestamp=${timestamp}&nonceStr=${nonceStr}&url=${url}`;
this.$axios.get(`test/get-signature${param}`).then(res=>{
console.log(res.data)
let signature = res.data.signature
let wx = window.wx;
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: 'your app_id', // 必填,公众号的唯一标识
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: nonceStr, // 必填,生成签名的随机串
signature: signature,// 必填,签名
jsApiList: ['getLocation'] // 必填,需要使用的JS接口列表
});
wx.ready(function(){
// alert('成功');
wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
var speed = res.speed; // 速度,以米/每秒计
var accuracy = res.accuracy; // 位置精度
alert("位置获取成功-"+latitude)
}
});
});
window.wx.error(function(res){
// alert('失败');
});
console.log(signature);
}).catch(err=>{
console.log(err);
})
},
onShareClick() {
console.log('sss');
}
}
}
</script>
8. 流程总结
- 以上 ,将该页面在微信中打开后,首先会在页面的声明周期
mounted
中触发getSignature
方法,在getSignature
方法中组装相关的参数,向后台发送一条请求,后台进行获取access_token
后,根据access_token
获得ticket
,按顺序拼装后再进行sha1
加密,将得到的signature
返回给前端,此时,前端就可以使用wx.config
填入相关的必要参数,在wx.ready(成功)
后就会调用匿名回调函数,走到wx.getLocation
方法,在传入type
后,在success
回调函数中即可弹出获取位置成功提示,至此,该流程结束
提示成功
网友评论