微信分享自定义:标题、内容、小图标

注意:实现此功能需要做的准备工作。
(1:):准备一个认证过的微信公众号。
(2):登录微信公众后台配置ip白名单,添加域名。
(3):获取公众号的app_id和app_secret





1. 在要分享的链接页面中(一般是首页),<head>标签中引入微信官方js

在这里插入图片描述

<script type="text/javascript" src="http://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

2.把下面这段js代码,放到页面中的任意位置,或者封装到js文件中,引入到页面。
注意:需要修改自己的后台请求路径,编辑文案,修改图标路径.

<script type="text/javascript">
		
		var appId = ""; // 必填,公众号的唯一标识
		var timestamp = ""; // 必填,生成签名的时间戳
		var nonceStr = ""; // 必填,生成签名的随机串
		var signature = "";// 必填,签名,见附录1
		var lineLink = window.location.href; //分享的网页,地址完整地址如:https://xxx.com/xxx/xxx.html

		$(function(){
		//发送ajax请求后台微信接口,返回需要的一些参数,见下面success中
			$.ajax({
				url : 'https://tests.wanxue.cn/shenlongpc/promote/getWXParam',//后台请求路径
				type : "POST",
				data : {
					url : lineLink
				},
				//后台响应回的数据
				success : function(res) {
					var r = eval(res);
					appId = r.appId;
					timestamp = r.timestamp;
					nonceStr = r.nonceStr;
					signature = r.signature;

					wx_fx();
				}
			});
		})

		function wx_fx(){
			wx.config({
				debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
				appId: appId, // 必填,公众号的唯一标识
				timestamp: timestamp, // 必填,生成签名的时间戳
				nonceStr: nonceStr, // 必填,生成签名的随机串
				signature: signature,// 必填,签名,见附录1
				jsApiList: [
					'onMenuShareTimeline', //分享给好友
					'onMenuShareAppMessage'	//分享到朋友圈
				] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
			});

			wx.ready(function () {
				//自定义分享,小图标,标题,内容
				var imgUrl = "http://xxx.com/images/img.png"; (填写完整的图标地址)
				var shareTitle = "此处填写分享的标题";
				var descContent = "此处填写分享的内容";
				
				//分享到朋友圈
				wx.onMenuShareTimeline({
					title: shareTitle,
					link: lineLink,
					imgUrl: imgUrl,
					success: function (res) {
						alert("分享成功!")
					},
					cancel: function (res) {
						alert("取消分享!")
					},
					fail: function (res) {
						alert("分享失败!");
					}

				});

				//分享给朋友
				wx.onMenuShareAppMessage({
					title: shareTitle,
					desc: descContent ,
					link: lineLink,
					imgUrl: imgUrl,
					success: function (res) {
						/*shared(shareLink, "friend", shareGid);*/
						alert("分享给朋友成功!");
					},
					fail: function (res) {
						alert("分享给朋友失败!" + JSON.stringify(res));
					}
				});
			});
		}
	</script>

3.编写后台代码,根据公众号的app_id/app_secret获取tiket。

@RequestMapping("/promote")
@Controller
public class PromoteController {

    @RequestMapping("/getWXParam")
    @ResponseBody
    public Map<String,String> getWXParam(String url){
        //ticket是公共的,所有用户进来用的都是一个ticket.微信官方规定ticket失效时间两小时,每天的获取次数也有限制,所以每次进入都先从redis中获取ticket,存取redis的方法需要根据自己项目修改.或者存到数据库中也可以.
        String ticket = RedisPoolTools.getRedis(RedisPoolTools.getDatabase(),"redis_ticket");
		//判断ticket是否失效
        if("".equals(ticket) || null == ticket){
            //微信公众号的appId和secret
            String appId =  "wx91fc8777e7516707";
            String secret= "254001781918a47a79643656226e8543";
            
			//请求微信官方接口,获取access_token
            String s = UrlTools.INSTANCE.httpURLConnection(null,null,"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appId+"&secret="+secret,"GET");
            JSONObject res1Json = JSONObject.parseObject(s);
            Map<String,Object> wxBack = (Map<String,Object>)res1Json;
            System.out.println("wxBack==="+wxBack);
            String access_token = wxBack.get("access_token").toString();
			
			//请求微信接口,获取ticket
            String url2 = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token +"&type=jsapi";
            System.out.println("获取jsapi_ticket的地址==="+url2);
            String res2 = UrlTools.INSTANCE.httpURLConnection(null, null, url2, "GET");
            System.out.println("获取jsapi_ticket的结果==="+res2);
            Map<String,Object> resMap2 = JsonUtil.parseJSON2Map(res2);
            try{
                ticket = resMap2.get("ticket").toString();
                //把取到的ticket存到redis中(ticket默认两小时失效),设置失效时间7140s,也就是119分钟
                RedisPoolTools.setRedis(RedisPoolTools.getDatabase(),"redis_ticket",ticket,7140);
            }catch (Exception e){
                throw new RuntimeException("获取jsapi_ticket失败!");
            }
        }
        //调用工具类
        return jsApiUtil.sign(ticket,url);
    }
}

再次注意:

  • 只有使用企业认证的公众号才能使用自定义分享的功能.代码中的appid和secret填写使用的公众号的.
  • 把线上服务器的ip地址和域名配置到公众号后台,把微信认证的一个.txt文件放到服务器的域名根目录下,我的项目springBoot项目,放在了服务器的static目录下了
    在这里插入图片描述
  1. 1:使用的工具类1: jsApiUtil
public class jsApiUtil {

    public static Map<String, String> sign(String jsapi_ticket, String url) {
        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写,且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + nonce_str +
                "&timestamp=" + timestamp +
                "&url=" + url;
        System.out.println(string1);

        try
        {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

        //Map<String,String> wxInfo = WXInfoApplication.getWXInfo(CookieUtil.getWxRegion());
        //微信公众号的appid,使用时需要修改
        String appId =  "wx91fc8777e7516707";
        ret.put("url", url);
        ret.put("appId",appId);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);

        return ret;
    }

    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}

4.2:使用的工具类2,把json转成map

public class JsonUtil {

	/**
	 * json转map
	 * @param jsonStr
	 * @return
	 */
	public static Map<String, Object> parseJSON2Map(String jsonStr){  
		Map<String, Object> map = new HashMap<String, Object>();  
		if(jsonStr!=null && !jsonStr.equals("")){
			if(jsonStr.indexOf("[")==0){
				jsonStr=jsonStr.substring(1,jsonStr.length()-1);
			}
			//最外层解析  
			JSONObject json = JSONObject.fromObject(jsonStr);  
			for(Object k : json.keySet()){  
				 Object v = json.get(k);   
				 //如果内层还是数组的话,继续解析  
				 if(v instanceof JSONArray){  
					 List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();  
					 Iterator<JSONObject> it = ((JSONArray)v).iterator();
					 while(it.hasNext()){  
						 JSONObject json2 = it.next();  
						 list.add(parseJSON2Map(json2.toString()));  
					 }  
					 map.put(k.toString(), list);  
				 } else {  
					 if(v.equals(null)){
						 v=new String();
					 }
					 map.put(k.toString(), v);  
				 }  
			}  
		}
		return map;  
	} 
}

5.使用的工具类3:请求外部接口工具类,可换成自己的方式发送http请求

public enum UrlTools {
	INSTANCE;
	/**
	 * lyc
	 * 接口调用  get/POST
	 */
	public String httpURLConnection (Map<String,Object> headers, String param, String url, String method) {

		String res = "";
		InputStream in = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		HttpURLConnection connection = null;
		PrintWriter out = null;
		try {
			URL u = new URL(url);
			// 将url 以 open方法返回的urlConnection  连接强转为HttpURLConnection连接  (标识一个url所引用的远程对象连接)
			// 此时cnnection只是为一个连接对象,待连接中
			connection = (HttpURLConnection) u.openConnection();
			// 设置连接输出流为true,默认false (post 请求是以流的方式隐式的传递参数)
			connection.setDoOutput(true);
			// 设置连接输入流为true
			connection.setDoInput(true);
			// 设置请求方式为post
			connection.setRequestMethod(method);
			// post请求缓存设为false
			connection.setUseCaches(false);
			// 设置该HttpURLConnection实例是否自动执行重定向
			connection.setInstanceFollowRedirects(true);
			//addRequestProperty添加相同的key不会覆盖,如果相同,内容会以{name1,name2}
			connection.setRequestProperty("Accept", "*/*");
			connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
			if(null != headers){
				setProperty(headers,connection);
			}
			// 建立连接 (请求未开始,直到connection.getInputStream()方法调用时才发起,以上各个参数设置需在此方法之前进行)
			connection.setConnectTimeout(10000);
			connection.setReadTimeout(10000);

			if("POST".equals(method) || "PUT".equals(method) && null != param){
				out = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(),"utf-8"));
				out.println(param);
				out.close();
			}
			if(connection.getResponseCode() == HttpURLConnection.HTTP_OK ||
					connection.getResponseCode() ==  HttpURLConnection.HTTP_CREATED ||
					connection.getResponseCode() ==  HttpURLConnection.HTTP_ACCEPTED){
				in = connection.getInputStream();
			}else{
				in = connection.getErrorStream();
			}

			isr = new InputStreamReader(in);
			br = new BufferedReader(isr);
			String line = "";
			StringBuilder content = new StringBuilder();
			while ((line = br.readLine()) != null) {
				content.append(line);
			}
			res = content.toString().trim();
			return res;
		} catch (Exception e) {
			//logger.error(" ** 接口访问失败 - "+url +"\r\n 错误信息:" + e.getClass()+" - "+e.getMessage());
			e.printStackTrace();
			throw new RuntimeException("接口访问失败");
		} finally {
			if (null != br) {
				try {
					br.close();
				} catch (IOException e) {
				}
			}

			if (null != isr) {
				try {
					isr.close();
				} catch (IOException e) {
				}
			}
			if (null != in) {
				try {
					in.close();
				} catch (IOException e) {
				}
			}
			if (null != out) {
				try {
					out.close();
				} catch (Exception e) {
				}
			}
			if(null != connection){
				try {
					connection.disconnect(); // 销毁连接
				} catch (Exception e) {
				}
			}
		}
	}
	//lyc
	private void setProperty(Map<String,Object> headers,HttpURLConnection connection){
		if(headers.containsKey("v")){
			connection.setRequestProperty("v",headers.get("v").toString());
		}
		if(headers.containsKey("p")){
			connection.setRequestProperty("p",headers.get("p").toString());
		}
		if(headers.containsKey("d")){
			connection.setRequestProperty("d",headers.get("d").toString());
		}
		if(headers.containsKey("t")){
			connection.setRequestProperty("t",headers.get("t").toString());
		}
		if(headers.containsKey("a")){
			connection.setRequestProperty("a",headers.get("a").toString());
		}
		if(headers.containsKey("Access-Control-Allow-Origin")){
			connection.setRequestProperty("Access-Control-Allow-Origin",headers.get("Access-Control-Allow-Origin").toString());
		}
        /*if(headers.containsKey("Content-Type")){
            connection.setRequestProperty("Content-Type",headers.get("Content-Type").toString());
        }*/
	}
}

注意:后台代码使用的时候需要修改的内容:

  • 存取redis的方式,改成自己的
  • 微信公众号的appid和secret改成你使用的公众号
  • 不要忘了把自己服务器的ip和项目域名配置公众号后台,进行认证.

前端代码使用注意:

  • 不要忘记引入使用微信的js文件jweixin-1.6.0.js
  • 修改后台请求路径
  • 修改js代码中的图标地址,编辑标题和内容文案.

6.效果
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值