H5实现微信分享自定义地图
这几天紧急开发一个拼团+砍价的H5微信小商城。技术用的是:前端Vue+Vant快速开发组件框架、后端java。
- 使用微信js-sdk流程图:
- 微信公众平台测试帐号申请地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
- 微信Js-sdk官方文档地址: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
这里记录一下微信分享自定义:
1. 申请微信测试号
测试账号拥有几乎所有的公众号接口,而个人只能申请订阅号,几乎没有接口可用,并且消息推送还会受到次数限制。如果只是做开发测试的话,那么测试帐号比较好用。
扫码登录即申请成功!登录后可以看到测试号的appID、appsecret
设置一下js安全接口域名,设置成自己的本机Ip即可。
扫码关注测试公众号,现在就可以使用微信的接口了。
2. 获取Access token
- 点我查看接口文档
可以看到文档就是让我们发起一个get请求, 携带三个参数:
这里指的就是测试号的appID、appsecret。
/*** * 获取微信的token * @return */ public static WxToken getAccessToken(String appId,String secret){ logger.info("getAccessToken()---begin"); WxToken wxToken=new WxToken(); Map<String, String> formDataPartMap = new HashMap<String, String>(); formDataPartMap.put("grant_type", Constans.WX_GRANT_TYPE); formDataPartMap.put("appId",appId); formDataPartMap.put("secret",secret); Result syncRequest; try { logger.info("getAccessToken()---开始调用微信基本接口获取accessToken"); syncRequest = OkHttpUtils.getData(Constans.WX_ACCESS_TOKEN_URL, formDataPartMap); if (ObjectUtils.isNotEmpty(syncRequest) && syncRequest.getCode() == 200) { JSONObject jsonObject = JSON.parseObject(syncRequest.getMsg()); logger.info("getAccessToken()---access_token:"+jsonObject); wxToken.setAccessToken(jsonObject.getString("access_token")); wxToken.setExpiresIn(jsonObject.getString("expires_in")); wxToken.setWxAppId(appId); logger.info("getAccessToken()---access_token:"+jsonObject.getString("access_token")); logger.info("getAccessToken()---expires_in:"+jsonObject.getString("expires_in")); logger.info("getAccessToken()---获取accessToken成功!!!"); } } catch (IOException e) { e.printStackTrace(); logger.info("getAccessToken()---获取AccessToken发生异常"); }
logger.info("getAccessToken()---end"); return wxToken; }
3. 获取jsapi_ticket
根据获取到的access_token来获取jsapi_ticket,也是get请求!
/*** * 获取微信的ticket * @param accessToken * @return */ public static String getTicket(String accessToken){ logger.info("getTicket()---begin"); String ticket = null ; Map<String, String> formDataPartMap = new HashMap<String, String>(); formDataPartMap.put("access_token", accessToken); formDataPartMap.put("type", "jsapi"); Result syncRequest; try { logger.info("getTicket()---开始调用微信基本接口获取ticket"); syncRequest = OkHttpUtils.getData(Constans.WX_TICKET_URL, formDataPartMap); if (ObjectUtils.isNotEmpty(syncRequest) && syncRequest.getCode() == 200) { JSONObject jsonObject = JSON.parseObject(syncRequest.getMsg()); jsonObject = JSON.parseObject(syncRequest.getMsg()); ticket = jsonObject.getString("ticket"); logger.info("getTicket()---ticket:"+jsonObject.getString("ticket")); logger.info("getTicket()---获取ticket成功!!!"); } } catch (IOException e) { e.printStackTrace(); }
logger.info("getTicket()---end"); return ticket; }
正常情况下,access_token 和 jsapi_ticket的有效期为7200秒,由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。
按照微信的推荐方案这两个方法必须要在服务端调用,并使用缓存或数据库存储。 解决方案: 在服务端启动后执行定时器,每隔7000秒定时刷新token及ticket。存储在数据库或缓存中间件例如: redis中, 并向客户端提供一个主动刷新token及ticket的方法
我这里为了减少项目的依赖性,存储在数据库。 如果项目中使用了redis,更加建议使用redis存储。代码如下:
@Componentpublic class ApplicationRunnerImpl extends BaseService implements ApplicationRunner {
private static Logger logger = LoggerFactory.getLogger(ApplicationRunnerImpl.class);
@Override public void run(ApplicationArguments args) throws Exception { //查询wx配置 WxServiceConfig wxServiceConfig = wxServiceConfigRepository.findOne(Constans.WX_SERVICE_CONFIG_ID); logger.info("通过实现ApplicationRunner接口,在springboot项目启动后执行方法"); logger.info("项目启动成功两秒后,执行Timer,后续每次执行间隔为7000秒"); Timer timer = new Timer(); timer.schedule(new TimerTask() { public void run() { logger.info("执行Timer开始"); logger.info("获取微信的accessToken"); // 获取微信的accessToken WxToken wxToken = WxTools.getAccessToken(wxServiceConfig.getWxAppId(),wxServiceConfig.getWxSecret()); logger.info("获取微信的ticket"); if(ObjectUtils.isNotEmpty(wxToken.getAccessToken())){ String ticket = WxTools.getTicket(wxToken.getAccessToken()); wxToken.setWxTicket(ticket); wxToken.setCreateTime(new Date()); WxToken save = wxTokenRepository.save(wxToken); if(ObjectUtils.isEmpty(save)) logger.info("更新或存储token信息失败"); }else{ logger.info("获取失败微信token失败,可能是没有绑定白名单或jssdk信息"); } logger.info("执行Timer结束"); } }, 2000, 7000 * 1000); } }
4. 生成签名
- 点我查看签名算法
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
/*** * 获取签名方法 * @param timestamp * @param nonceStr * @param url * @param ticket * @return * @throws Exception */ public static String getSign(String timestamp, String nonceStr,String url,String ticket) throws Exception { logger.info("getSign()---begin"); StringBuffer sb = new StringBuffer(); sb.append("jsapi_ticket=").append(ticket).append("&"); sb.append("noncestr=").append(nonceStr).append("&"); sb.append("timestamp=").append(timestamp).append("&"); sb.append("url=").append(url); logger.info("getSign()---param:"+sb.toString()); String sha1 = DigestUtils.sha1Hex(sb.toString().getBytes("UTF-8")); logger.info("getSign()---sha1: "+sha1); logger.info("getSign()---end"); return sha1; }
5. 引入js文件
Vue项目引入方式:
npm install weixin-js-sdk //下载sdk
import wx from 'weixin-js-sdk' #需要使用的页面引入
使用直接 wx.xxx
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)
6. config接口注入权限验证配置
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用)
wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: wxConfig.appId, // 必填,公众号的唯一标识 timestamp: wxConfig.timestamp, // 必填,生成签名的时间戳 nonceStr: wxConfig.nonceStr, // 必填,生成签名的随机串 signature: wxConfig.signature, // 必填,签名 服务端通过token和ticket生成的签名 jsApiList: [ "updateAppMessageShareData", //<strong>自定义“分享给朋友”及“分享到QQ”按钮的分享内容(1.4.0)</strong> "updateTimelineShareData", //<strong>自定义“分享给朋友圈”及“分享到QQ空间”按钮的分享内容(1.4.0)</strong> "openLocation" //打开地图 ], // 必填,需要使用的JS接口列表 如果没填 接口会使用不了 });
7. 通过ready接口处理成功验证
config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
wx.ready(()=>{ //需在用户可能点击分享按钮前就先调用 wx.updateAppMessageShareData({ //自定义“分享给朋友”及“分享到QQ”按钮的分享内容(1.4.0) title: this.wxUserInfo.nickname+': 车位万元优惠重磅来袭!车位砍价活动火热进行中...', // 分享标题 desc: '车位万元优惠重磅来袭!', // 分享描述 link: 'http://192.168.0.112:8080/car?bargain_openid='+this.wxUserInfo.openid, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 imgUrl: 'http://47.119.164.247:9000/zapi/020747bb9e97b7fc45c96741e104025.jpg', // 分享图标 success: function () { // 设置成功 } }); wx.updateTimelineShareData({ //自定义“分享给朋友圈”及“分享到QQ动态”按钮的分享内容(1.4.0) title: this.wxUserInfo.nickname+': 车位万元优惠重磅来袭!车位砍价活动火热进行中...', // 分享标题 desc: '车位万元优惠重磅来袭!', // 分享描述 link: 'http://192.168.0.112:8080/car?bargain_openid='+this.wxUserInfo.openid, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 imgUrl: 'http://47.119.164.247:9000/zapi/020747bb9e97b7fc45c96741e104025.jpg', // 分享图标 success: function () { // 设置成功 } }); });
8. 使用接口
所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数:
- success:接口调用成功时执行的回调函数。
- fail:接口调用失败时执行的回调函数。
- complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。
- cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。
- trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。
例如:
wx.openLocation({ latitude: 50.199767, // 纬度,浮点数,范围为90 ~ -90 longitude: 135.971021, // 经度,浮点数,范围为180 ~ -180。 name: '万达广场', // 位置名 address: '街60-160号附近', // 地址详情说明 scale: 15, // 地图缩放级别,整型值,范围从1~28。默认为最大 infoUrl: '', // 在查看位置界面底部显示的超链接,可点击跳转 success: function () { // 设置成功 } });
附上我的http请求方法:
/** * get请求,同步方式,获取网络数据, * * @param url * @return */ public static Result getData(String url) throws IOException { // 1 构造Request Request.Builder builder = new Request.Builder().get().url(url); OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(60, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS).build(); // 2 将Request封装为Call Call call = okHttpClient.newCall(builder.build()); // 3 执行Call,得到response Response response = call.execute(); if (response.isSuccessful()) { return new Result(Result.CODE_SUCCESS, response.body().string()); } else { return new Result(Result.CODE_ERROR, response.message()); } }
public static Result getData(String url, Map<String, String> params) throws IOException { StringBuilder urlPath = new StringBuilder(url); if (ObjectUtils.isNotEmpty(params)) { urlPath.append("?"); for (Map.Entry<String, String> param : params.entrySet()) { urlPath.append(param.getKey() + "=" + param.getValue() + "&"); } urlPath.deleteCharAt(urlPath.length() - 1); } System.out.println(urlPath.toString()); return getData(urlPath.toString()); }
OK完工。以上就是H5实现微信分享自定义&地图的全部内容,如果还有其他不懂的可以添加右下角微信,欢迎骚扰!
大家也可以点击我的gitee来获取我的其他项目源码。 拜拜!
H5实现微信分享自定义地图相关推荐
- uniapp 转H5 实现微信浏览器自定义分享样式
uniapp 转H5后 实现微信浏览器自定义分享样式 uniapp 项目转 h5 1.在manifest.json文件中,找到H5配置一下路径,需要注意这个名字需要和布到线上的文件夹名字一致 2.就是 ...
- PHP---微信JS-SDK获取access_token/jsapi_ticket/signature权限签名算法,php/thinkphp实现微信分享自定义文字和图片...
PHP---微信JS-SDK获取access_token/jsapi_ticket/signature权限签名算法, php/thinkphp实现微信分享自定义文字和图片. 一.先看微信JS-SDK文 ...
- 基于静态URL的微信分享自定义缩略图及标题和摘要
在静态页中实现微信分享自定义缩略图比动态页分享要复杂.下面是示例页面: 分享的效果(缩略图及标题.摘要是自己指定): 实现难点: (1)URL是变化的,我们分享一次后,微信会自动在分享的地址后增加了一 ...
- 微信分享自定义标题和图片,开发者工具没问题,真机调试失败
昨天亲身经历,微信分享开发者工具调试没问题,但是真机调试失败,说明配置是没问题的,历经一天发现是缓存的问题 解决方案: 删除掉微信进程后,缓存没有被彻底清除 安卓手机打开 debugtbs.qq.co ...
- 微信分享自定义多次分享设置
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 微信分享中,初始的头部,一定得先放好,即wx.config中 ...
- android开发微信分享隐藏logo,前两天刚刚做了微信分享自定义logo和文字,做个标记,从零开始记录...
首先要有一个认证过的公众号,才会有权限 打开微信的jsskd 使用说明 在页面中引入微信的js文件 引入后 配置config wx.config({ debug: true, // 开启调试模式,调用 ...
- H5页面微信分享和手Q分享设置
RT: 一. 手Q分享: 如下代码所示:设置好 description,name,image,即可,唯一注意的是image最好是200*200,要不然过小不美观,过大加载太慢 <head> ...
- 微信分享自定义图片标题摘要-微信官方API
我们平时在使用微信内置浏览器打开网页想要分享给好友或者发到朋友圈的时候经常会遇到这样的问题, 别人的网页分享的时候是这样的: 而我们自己的网页分享后这这样的: 看到有人说不做任何设置,微信分享时会自动 ...
- 微信分享自定义内容功能代码
嗯,废话不多说,直接上代码. 这里我把有关微信分享的接口的代码单独放在了一个js文件中 wxshare.js文件: function getshare(){// 微信配置wx.config({ ...
最新文章
- SQL基础学习总结:3(select语句基础算术运算符比较运算符)
- html显示隐藏密码,Web前端,登录密码显示隐藏眼睛
- “第三届中国行业互联网大会暨CIO班12周年年会”成功举行
- mongodb,redis,mysql 简要对比
- android sharedpre,Android SharedPreferences四种操作模式使用详解_Android_脚本之家
- JQuery $.each遍历JSON字符串报Uncaught TypeError:Cannot use 'in' operator to search for
- python查看数据大小_python 监控文件大小
- 转个x64的Devcon
- 钉钉的微应用如何测试;
- juce教程005-中文显示
- 数据库优化之泛泛而谈
- 超过3万Mac已感染 “银麻雀”病毒 最新m1芯片也中招
- matlab 图片合成视频
- VS2015|Visual Studio Enterprise 2015简体中文版(企业版)
- php--如何编写一个简易的论坛
- python学的好,牢饭吃的早欸嘿
- 电脑WLAN连接异常:自上次连接后,某些信息已更改。我们还需要一些信息才能完成连接。
- 富士通DPK8400E打印机
- htc x920e刷android7.0,HTC X920e (Butterfly)一键刷机图文教程
- 总结49种软件测试方法,你知道几个?