美文网首页
分享至微信的页面怎么使用微信的api获取位置信息

分享至微信的页面怎么使用微信的api获取位置信息

作者: 木头就是我呀 | 来源:发表于2020-02-13 11:30 被阅读0次

    要实现一个如下功能:
    在分享到微信的页面,怎么使用微信的接口获取定位信息

    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
                + "&timestamp="+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回调函数中即可弹出获取位置成功提示,至此,该流程结束
      提示成功

    相关文章

      网友评论

          本文标题:分享至微信的页面怎么使用微信的api获取位置信息

          本文链接:https://www.haomeiwen.com/subject/ovbqfhtx.html