Java-微信H5分享功能

article/2025/9/13 18:41:55

操作前必看

微信自带的点击按钮分享已经下架了,目前只支持在微信浏览器点击右上角的分享,自己配置分享参数,而且目前分享参数也无法使用。

原因:响应国家反垄断规章,微信调整可实现访问外链;
异常:现在点击微信聊天发出来的链接,再点分享会直接成为字符串链接形式
解决办法:

1.将链接添加至公众号的自定义菜单中,从公众号菜单进入分享
2.扫描二维码分享
3.将链接保存至微信收藏中,从我的收藏进入分享
其余其他地方进入分享都是链接形式

注意

切记缓存 jsapi_ticketaccessToken,每天的请求有限制

没有公众号,那么申请测试号进行测试,但是必须有域名,目前的内网穿透工具好像都无法使用了

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

进入上方网址,微信扫码登录即可得到一个拥有微信分享权限的测试号。暂时只需要appID和appsecret。JS接口安全域名填自己的域名,不需要带http/https。接口配置信息配置需要我们完成后端代码才能配置。

在这里插入图片描述

微信分享接口

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;@Controller
@RequestMapping(value = "/wechatshare")
public class WeChatShareController {private final static Logger log = LoggerFactory.getLogger(WeChatShareController.class);/*** 获取微信加密信息* @return*/@RequestMapping(value = "/getsignature")@ResponseBodypublic Map<String, Object> toTranscript(String urls) {Map<String, Object> data = new HashMap<String, Object>();Map<String, Object> wxInfo = new HashMap<>();try {String accessToken = WeChatUitl.getAccessToken();String jsapiTicket = WeChatUitl.getTicket(accessToken);String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//随机字符串String timestamp = String.valueOf(System.currentTimeMillis()/ 1000);// 时间戳String params = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;//将字符串进行sha1加密String signature = WeChatUitl.getSHA1(params);//微信appIdString appId = WeChatUitl.appIdWx;wxInfo.put("appId", appId);wxInfo.put("accessToken", accessToken);wxInfo.put("jsapi_ticket", jsapiTicket);wxInfo.put("timestamp", timestamp);wxInfo.put("nonceStr", noncestr);wxInfo.put("signature", signature);wxInfo.put("msg", "success");wxInfo.put("status", "1");wxInfo.put("code", "1");log.info("微信分享成功");return wxInfo;} catch (Exception e) {wxInfo.put("code", "0");wxInfo.put("status", "0");wxInfo.put("msg", "error");log.error("获取微信加密信息" + e.getMessage(), e);return wxInfo;}}
}

微信分享工具类

import net.sf.json.JSONObject;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class WeChatUitl {// 获取token的描述,自己定义就可以了public static final String tokenWx = "xxxxxxxxxxxxxxx";// 微信appid---微信公众平台public static final String appIdWx = "xxxxxxxxxxxxxx";// 微信AppSecret---微信公众平台public static final String appSecretWx = "xxxxxxxxxxxxxxxxxxxxxxxxxx";/*** 获取access_token** @return*/public static synchronized  String getAccessToken() {String access_token = "";String grant_type = "client_credential";//获取access_token填写client_credential//这个url链接地址和参数皆不能变String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=" + grant_type + "&appid=" + appIdWx + "&secret=" + appSecretWx;try {URL urlGet = new URL(url);HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();http.setRequestMethod("GET"); // 必须是get方式请求http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");http.setDoOutput(true);http.setDoInput(true);http.connect();InputStream is = http.getInputStream();int size = is.available();byte[] jsonBytes = new byte[size];is.read(jsonBytes);String message = new String(jsonBytes, "UTF-8");JSONObject demoJson = JSONObject.fromObject(message);access_token = demoJson.getString("access_token");is.close();} catch (Exception e) {e.printStackTrace();}return access_token;}/*** 获取jsapi_ticket** @param access_token* @return*/public static synchronized  String getTicket(String access_token) {String ticket = null;String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi";//这个url链接和参数不能变try {URL urlGet = new URL(url);HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();http.setRequestMethod("GET"); // 必须是get方式请求http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");http.setDoOutput(true);http.setDoInput(true);http.connect();InputStream is = http.getInputStream();int size = is.available();byte[] jsonBytes = new byte[size];is.read(jsonBytes);String message = new String(jsonBytes, "UTF-8");JSONObject demoJson = JSONObject.fromObject(message);System.out.println("JSON字符串:" + demoJson);ticket = demoJson.getString("ticket");is.close();} catch (Exception e) {e.printStackTrace();}return ticket;}/*** SHA、SHA1加密** @parameter: str:待加密字符串* @return: 加密串**/public static String getSHA1(String str) {try {MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1"); //如果是SHA加密只需要将"SHA-1"改成"SHA"即可digest.update(str.getBytes());byte messageDigest[] = digest.digest();// Create Hex StringStringBuffer hexStr = new StringBuffer();// 字节数组转换为 十六进制 数for (int i = 0; i < messageDigest.length; i++) {String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);if (shaHex.length() < 2) {hexStr.append(0);}hexStr.append(shaHex);}return hexStr.toString();} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return null;}
}

h5页面示例

$(function () {var winUrl = window.location.href.split("#")[0];/* if(winUrl.indexOf('from=singlemessage')>0 || winUrl.indexOf('isappinstalled')>0){winUrl = winUrl.split('?from=singlemessage')[0]} */var meta = document.getElementsByTagName('meta');var share_desc = '';for (i in meta) {if (typeof meta[i].name != "undefined" && meta[i].name.toLowerCase() == "description") {share_desc = meta[i].content;}}$.ajax({type: "post",url: "/post/getShareSignature",crossDomain: true,dataType: "json",contentType: "application/json; charset=utf-8",data: JSON.stringify({"articleUrl": encodeURIComponent(winUrl)}),success: function (msg) {//console.log(" timestamp:" + msg.data.timestamp + " ; noncestr:" + msg.data.noncestr + ";  signature:" + msg.data.signature);wx.config({debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。appId: "wx91f855a7c7f4187b", // 必填,公众号的唯一标识timestamp: msg.data.timestamp, // 必填,生成签名的时间戳nonceStr: msg.data.noncestr, // 必填,生成签名的随机串signature: msg.data.signature, // 必填,签名,见附录1jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2});wx.ready(function () {var title, img_url;if (winUrl.indexOf('post') != -1) {//IOS系统分享时读取图片路径会出现问题 用 encodeURI 来处理下title = $("#articleTitle").val();img_url = encodeURI($("#coverImg").val());} else if (winUrl.indexOf('school') != -1) {title = document.title;img_url = encodeURI($("#schoolBadge").attr("src"));} else if (winUrl.indexOf('seventy') != -1) {title = document.title;img_url = encodeURI('https://xsn.com.cn/fileDir/cnypaData/seventy.jpg');} else {title = document.title;img_url = encodeURI(location.href.split('.cn/')[0] + '.cn/img/Group.png')}//分享到朋友圈wx.onMenuShareTimeline({title: title, // 分享标题link: winUrl, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致imgUrl: img_url, // 分享图标success: function () {console.log('已分享');},cancel: function () {console.log('已取消');},fail:function(res){alert(JSON.stringify(res))}}); //分享给微信好友wx.onMenuShareAppMessage({title: title, // 分享标题desc: share_desc,link: winUrl, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致imgUrl: img_url, // 分享图标type: '', // 分享类型,music、video或link,不填默认为linksuccess: function () {console.log('已分享');},cancel: function () {console.log('已取消');},fail:function(res){alert(JSON.stringify(res))}});wx.error(function (res) {console.log("res:", res)})});},error: function (XMLHttpRequest, textStatus, errorThrown) {console.log("error" + errorThrown);}});})//  微信js - sdk分享 end

http://chatgpt.dhexx.cn/article/unwDsqkO.shtml

相关文章

计算机考证照片尺寸规格

1&#xff09;照片应为考生本人近期正面免冠彩色证件照。 2&#xff09;成像区上下要求头上部空1/10&#xff0c;头部占7/10&#xff0c;肩部占1/5&#xff0c;左右各空1/10。采集的图象大小最小为192144&#xff08;高宽&#xff09;&#xff0c;成像区大小为48mm33mm&#x…

2016 PayPal商家账户界面 如何设置开启IPN

登陆账户到www.paypal.com点击右上方“用户信息”〉“用户信息与设置”&#xff0c;在打开的页面中&#xff0c;点击左侧“销售工具”菜单页面右侧找到“即使付款通知”&#xff0c;点击“更新”链接勾选“接收即使付款通知消息&#xff08;已启用&#xff09;”&#xff0c;并…

paypal IPN and PDT

paypal IPN and PDT 相关文档说明&#xff1a; https://developer.paypal.com/docs/classic/ipn/gs_IPN/ https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNTesting/ https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNPDTAnAltern…

paypal付款通知IPN

什么是即时付款通知IPN 当您收到新的付款交易或者已发生的付款交易的状态发生变化时&#xff0c;PayPal都将异步&#xff08;即不作为网站付款流程的一部分&#xff09; 发送付款详细数据到您所指定的URL&#xff0c;以便您了解买家付款的具体情况并做出相应的响应。这个过程我…

paypal 新注册帐号有哪些问题,paypal EC 和paypal checkout 如何设置账户IPN\签名等

一、IPN如何设置 IPN的设置 https://www.paypal.com/cgi-bin/customerprofileweb?cmd_profile-ipn-notify 二、paypal EC的用户名、密码、签名的设置 https://www.paypal.com/businessprofile/mytools/apiaccess/firstparty/signature 三、新账户提示该商家目前无法接收pa…

paypal的IPN机制

paypal对接时发现有这么一个机制&#xff0c;看起来还不错&#xff0c;起到了防止篡改欺诈行为&#xff0c;保证了通信的安全性&#xff0c;但会增加几次通信。

paypal IPN返回

1.设定返回的地址 目标&#xff1a;登录paypal-->用户信息-->我的销售工具-->即时付款通知-->编辑并填写url 填写的URL必须为公网的&#xff0c;不能为局域网&#xff0c;要不就无法接收到paypal发送的信息 2.编写IPN.jsp (此代码为官方代码) //从 PayPal 出读取 P…

沙箱环境和正式环境【PayPal接入(java)】【IPN通知问题】项目实战干货总结记录!

如果你是第一次接入paypal&#xff0c;相信本文的每一个地方都会对你有帮助的&#xff01;&#xff01;因为这篇文章都是一个一个的坑踩出来的&#xff01; 一、接入paypal环境准备&#xff1a; 1、注册paypal账号 https://www.paypal.com 注册“商家账号”&#xff0c;完成…

php paypal ipn,PHP 开发详解:PayPal Instant Payment Notification (IPN)

上次在 PHP 开发详解&#xff1a;PayPal Payment Data Transfer (PDT) 一文中介绍了网站集成 Paypal 付款功能并如何将付款数据返回&#xff0c;能够使得用户在付款完成后继续回到网站上来&#xff0c;并将付款信息告知用户。但是 PayPal Payment Data Transfer 这样的数据返回…

【Paypal】即时付款通知IPN

什么是即时付款通知IPN 当您收到新的付款交易或者已发生的付款交易的状态发生变化时&#xff0c;PayPal都将异步&#xff08;即不作为网站付款流程的一部分&#xff09; 发送付款详细数据到您所指定的URL&#xff0c;以便您了解买家付款的具体情况并做出相应的响应。这个过程我…

java集成paypal ipn响应问题

在集成paypal 测试ipn如果不回复会多次调用ipn 直到上限或者得到响应。 发现一个非常奇怪的问题代码中未返回响应码&#xff0c;但是paypal那边却显示响应成功&#xff1f; 求大神指点&#xff0c;是因为服务器接收成了吗&#xff1f;所以自动回复了200&#xff1f; spring …

paypal消息通知IPN

paypal支付成功时会实时的把支付交易信息返回给我们&#xff0c;java会返回一个payment对象&#xff0c;里面有交易的信息包含付款人&#xff0c;订单费用&#xff0c;订单的收货地址&#xff0c;收款人&#xff0c;交易号等信息。我们拿到了这个payment就表示支付成功了&#…

paypal资料

什么是即时付款通知IPN 当您收到新的付款交易或者已发生的付款交易的状态发生变化时&#xff0c;PayPal都将异步&#xff08;即不作为网站付款流程的一部分&#xff09; 发送付款详细数据到您所指定的URL&#xff0c;以便您了解买家付款的具体情况并做出相应的响应。这个过程我…

css 上下布局 flex,Css Flex布局

Flex布局是Css3中新加入的额外布局系统。 传统布局基于盒模型,依赖“display”、“position”、“float”属性,对于特殊布局非常不便。 因此2009年,W3C提出新的布局方案-Flex布局,但由于浏览器兼容问题,Flex布局并没有大范围铺开。 实现Flex布局的条件 1.必须有一个父级容…

html flex 上中下布局,flex 布局

FlexiableBox即是弹性盒,用来进行弹性布局,一般跟rem(rem伸缩布局(转))连起来用比较方便,flexbox负责处理页面布局,然后rem处理一些flex顾及不到的地方(rem伸缩布局主要处理尺寸的适配问题),布局还是要传统布局的。 布局的传统解决方案,基于盒状模型,依赖display属性 +p…

详细讲解flex布局

一、flex布局基本概念 在没有使用flex布局之前&#xff0c;常用布局有&#xff1a;流式布局&#xff0c;浮动布局&#xff0c;定位布局等等。这些布局的缺陷是子元素需要自己控制自己在父元素中的位置&#xff0c;还要注意父元素高度坍塌。 flex布局是一种布局模型&#xff0…

CSS常用布局二(flex布局)

flex布局 前言&#xff1a;flex是flexible box的缩写&#xff0c;译为“弹性布局”&#xff0c;用来为盒模型提供最大的灵活性&#xff0c;任何一个容器都可以指定为flex布局&#xff0c;只需要设置“display:flex"即可&#xff1b;行内元素可以通过设置”display:inline…

flex布局(详解)

目录 前言 一、何为Flex布局 二、基本概念 三、容器的属性 3.1 flex-direction属性 3.2 flex-wrap属性 3.3 flex-flow 3.4 justify-content属性 3.5 align-items属性 3.6 align-content属性 四、项目的属性 4.1 order属性 4.2 flex-grow属性 4.3 flex-shrink属性 …

Flex布局详解

Flex 布局详解 一、入门 1. flex 是什么&#xff1f; flex 是 Flexible Box 的缩写&#xff0c;就是弹性盒子布局的意思 2. 为什么我们需要 flex? 解决元素居中问题 自动弹性伸缩&#xff0c;合适适配不同大小的屏幕&#xff0c;和移动端 3.flex 常见术语 三个2 序号简…