微信是一个很不错的传播平台,最近公司需要做一个新年贺卡,使用html5制作一个很小的动画,然后发送给客户,不需要和后台有任何的联系,一个很简单的功能,需要利用微信的分享功能,毕竟微信分享的带小图片、简介、标题比发送一个链接要比一个光秃秃的链接要高大上的多。好了,废话不多说了,进入正题吧。

刚开始我也到网上去搜了一下,看到好多这个版本的,我也贴一下:

var shareData = {
"appid": appid, //公众号的appID
"img_url": imgUrl, //缩略图地址
"img_width": "120", //图片的宽度
"img_height": "120",//图片的高度
"link": lineLink, //分享的链接
"desc": descContent,//摘要的信息
"title": shareTitle //分享的标题,默认为网页标题
}; function shareFriend() {
WeixinJSBridge.invoke('sendAppMessage',shareData, function(res) {
//定义分享完成后的事
alert(dasd);
})
}
function shareTimeline() {
WeixinJSBridge.invoke('shareTimeline',shareData, function(res) {
//_report('timeline', res.err_msg);
});
}
// 当微信内置浏览器完成内部初始化后会触发WeixinJSBridgeReady事件。
document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {
// 发送给好友
WeixinJSBridge.on('menu:share:appmessage', function(argv){
shareFriend();
});
// 分享到朋友圈
WeixinJSBridge.on('menu:share:timeline', function(argv){
shareTimeline();
});
}, false);

可能这个版本在微信没有发布js-sdk时是有用的,但是现在微信好像把这个方法设置了权限,这个方法已经不可用了,所以我到微信官方去看了一下,微信js-sdk已经支持开发接口支持微信分享了,怎么实现,下面一一道来:

微信官方js-sdk链接地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html 有兴趣可以自己去研究研究,下面只是我自己的一些经验,水平有限,有错误之处欢迎大家指出。

1. 要使用js-sdk,首先你得拥有一个微信认证过的订阅号或者服务号(个人认为如果开发的还是服务号好),然后按照微信js-sdk api的步骤来,先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。js接口安全域名可以设置三个,意思是你的网页要想使用js-sdk,访问就必须在这个域名下(如果域名带有端口号,设置的时候也必须带有端口号,微信上虽然说只支持80端口,但是我用其他端口好像也可以)。

2. 在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.0.0.js

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

3.通过config接口注入权限验证配置,所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。这里只说分享朋友圈和分享给朋友接口。

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

4.通过ready接口处理成功验证。

wx.ready(function () {
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
var shareData = {
title: title, // 分享标题
desc: desc, // 分享描述
link: link, //网页地址
imgUrl: imgUrl, //小图片的地址
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
};
wx.onMenuShareAppMessage(shareData);
wx.onMenuShareTimeline(shareData);
});

5.以上就是微信文档中的处理js-sdk接口的基本步骤,完成了这些,就可以完成一个如下的分享框:

6.上面的这些步骤都是微信文档上有的,copy就行,我个人觉得初次接触,微信js-sdk的config配置相对来说是要复杂一点。就是第三点里面的签名比较难一点,下面我就详细的说一下我是怎么获得配置的参数的(appid,timestamp,noncestr,signature);首先找到js-sdk生成签名的文档,阅读发现signature的生成是需要密钥的,就是我们公众号AppSecret,这个东西是不能被别人知道的,所以我们处理密钥一定要在后台处理,在html处理的话会泄漏你的公众号关注者的信息的。所以我们得在后台写一个接口,用来返回config里的配置信息;后台怎么处理呢?(后台是用java写的)

1>首先随机生成一个字符串(noncestr)和一个随机时间戳(timestamp),这就解决了两个配置项;

noncestr  = Double.toString(Math.random()).substring(2, 15);//随机字符串
timeStamp =((int)(new Date().getTime()/1000))+"";//随机时间戳

2>然后就的获得微信的基础支持,访问微信的https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET接口,获得返回来的access_token;

public String getAccess_token(){
System.out.println("重新请求access_token");
String access_token = "";
String str = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&";
str += "appid=" + APPID + "&secret=" + APPSECRET;
try {
URL url = new URL(str);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(CONNECTTIMEOUT);
connection.setReadTimeout(READTIME);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"utf-8"));
StringBuffer stringBuffer = new StringBuffer();
String temp = "";
while((temp = bufferedReader.readLine())!= null){
stringBuffer.append(temp);
System.out.println(temp);
}
String result = stringBuffer.toString();
JSONObject root = JSONObject.fromObject(result);
access_token = root.getString("access_token");
bufferedReader.close(); } catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return access_token;
}

3>获得微信的access_token后,就可以获得jsapi_ticket了,访问微信的https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi接口,获得返回来的jsapi_ticket;

public String getJsapi_ticket(String access_token){
System.out.println("重新请求jsapi_ticket");
String jsapi_ticket = "";
String str = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi";
try {
URL url = new URL(str);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(CONNECTTIMEOUT);
connection.setReadTimeout(READTIME);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"utf-8"));
StringBuffer stringBuffer = new StringBuffer();
String temp = "";
while((temp = bufferedReader.readLine())!= null){
stringBuffer.append(temp);
}
String result = stringBuffer.toString();
JSONObject root = JSONObject.fromObject(result);
jsapi_ticket = root.getString("ticket");
bufferedReader.close(); } catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return jsapi_ticket;
}

4>获得jsapi_ticket,noncestr,timestamp还有你的网页地址后就可以生成签名了;

public WeiXinJsServer(String url,HttpServletRequest request) {
this.noncestr = Double.toString(Math.random()).substring(2, 15);
this.timeStamp =((int)(new Date().getTime()/1000))+"";
String access_token = getAccess_token();
String Jsapi_ticket = getJsapi_ticket(access_token);
String str = "jsapi_ticket=" + Jsapi_ticket + "&noncestr=" + noncestr + "&timestamp="+ timeStamp +"&url=" + url;
this.signature = new SHA1().getDigestOfString(str.getBytes());
}

5>最后在奉上sha1算法;

public class SHA1 {
private final int[] abcde = {
0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
};
private int[] digestInt = new int[5];
private int[] tmpData = new int[80];
private int process_input_bytes(byte[] bytedata) {
System.arraycopy(abcde, 0, digestInt, 0, abcde.length);
byte[] newbyte = byteArrayFormatData(bytedata);
int MCount = newbyte.length / 64;
for (int pos = 0; pos < MCount; pos++) {
for (int j = 0; j < 16; j++) {
tmpData[j] = byteArrayToInt(newbyte, (pos * 64) + (j * 4));
}
encrypt();
}
return 20;
}
private byte[] byteArrayFormatData(byte[] bytedata) {
int zeros = 0;
int size = 0;
int n = bytedata.length;
int m = n % 64;
if (m < 56) {
zeros = 55 - m;
size = n - m + 64;
} else if (m == 56) {
zeros = 63;
size = n + 8 + 64;
} else {
zeros = 63 - m + 56;
size = (n + 64) - m + 64;
}
byte[] newbyte = new byte[size];
System.arraycopy(bytedata, 0, newbyte, 0, n);
int l = n;
newbyte[l++] = (byte) 0x80;
for (int i = 0; i < zeros; i++) {
newbyte[l++] = (byte) 0x00;
}
long N = (long) n * 8;
byte h8 = (byte) (N & 0xFF);
byte h7 = (byte) ((N >> 8) & 0xFF);
byte h6 = (byte) ((N >> 16) & 0xFF);
byte h5 = (byte) ((N >> 24) & 0xFF);
byte h4 = (byte) ((N >> 32) & 0xFF);
byte h3 = (byte) ((N >> 40) & 0xFF);
byte h2 = (byte) ((N >> 48) & 0xFF);
byte h1 = (byte) (N >> 56);
newbyte[l++] = h1;
newbyte[l++] = h2;
newbyte[l++] = h3;
newbyte[l++] = h4;
newbyte[l++] = h5;
newbyte[l++] = h6;
newbyte[l++] = h7;
newbyte[l++] = h8;
return newbyte;
}
private int f1(int x, int y, int z) {
return (x & y) | (~x & z);
}
private int f2(int x, int y, int z) {
return x ^ y ^ z;
}
private int f3(int x, int y, int z) {
return (x & y) | (x & z) | (y & z);
}
private int f4(int x, int y) {
return (x << y) | x >>> (32 - y);
}
private void encrypt() {
for (int i = 16; i <= 79; i++) {
tmpData[i] = f4(tmpData[i - 3] ^ tmpData[i - 8] ^ tmpData[i - 14] ^
tmpData[i - 16], 1);
}
int[] tmpabcde = new int[5];
for (int i1 = 0; i1 < tmpabcde.length; i1++) {
tmpabcde[i1] = digestInt[i1];
}
for (int j = 0; j <= 19; j++) {
int tmp = f4(tmpabcde[0], 5) +
f1(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
tmpData[j] + 0x5a827999;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int k = 20; k <= 39; k++) {
int tmp = f4(tmpabcde[0], 5) +
f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
tmpData[k] + 0x6ed9eba1;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int l = 40; l <= 59; l++) {
int tmp = f4(tmpabcde[0], 5) +
f3(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
tmpData[l] + 0x8f1bbcdc;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int m = 60; m <= 79; m++) {
int tmp = f4(tmpabcde[0], 5) +
f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
tmpData[m] + 0xca62c1d6;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int i2 = 0; i2 < tmpabcde.length; i2++) {
digestInt[i2] = digestInt[i2] + tmpabcde[i2];
}
for (int n = 0; n < tmpData.length; n++) {
tmpData[n] = 0;
}
}
private int byteArrayToInt(byte[] bytedata, int i) {
return ((bytedata[i] & 0xff) << 24) | ((bytedata[i + 1] & 0xff) << 16) |
((bytedata[i + 2] & 0xff) << 8) | (bytedata[i + 3] & 0xff);
}
private void intToByteArray(int intValue, byte[] byteData, int i) {
byteData[i] = (byte) (intValue >>> 24);
byteData[i + 1] = (byte) (intValue >>> 16);
byteData[i + 2] = (byte) (intValue >>> 8);
byteData[i + 3] = (byte) intValue;
}
private static String byteToHexString(byte ib) {
char[] Digit = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
'D', 'E', 'F'
};
char[] ob = new char[2];
ob[0] = Digit[(ib >>> 4) & 0X0F];
ob[1] = Digit[ib & 0X0F];
String s = new String(ob);
return s;
}
private static String byteArrayToHexString(byte[] bytearray) {
String strDigest = "";
for (int i = 0; i < bytearray.length; i++) {
strDigest += byteToHexString(bytearray[i]);
}
return strDigest;
}
public byte[] getDigestOfBytes(byte[] byteData) {
process_input_bytes(byteData);
byte[] digest = new byte[20];
for (int i = 0; i < digestInt.length; i++) {
intToByteArray(digestInt[i], digest, i * 4);
}
return digest;
}
public String getDigestOfString(byte[] byteData) {
return byteArrayToHexString(getDigestOfBytes(byteData));
}
public static void main(String[] args) {
String data = "123456";
System.out.println(data);
String digest = new SHA1().getDigestOfString(data.getBytes());
System.out.println(digest);
}
}

6>最后在页面调用一下就可以了。

$(document).ready(function(e) {
var url = location.href;
$.ajax({
url:"http://test/WeiXinJsSdkConfiger",
data:{
"url":url
}, //以键/值对的形式
async : true,
dataType : "jsonp",
jsonp: "callbackparam",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)
jsonpCallback:"success_jsonpCallback",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名
success : function(data) {
wx.config({
debug: false,
appId: data.appid,
timestamp: data.timeStamp,
nonceStr: data.noncestr,
signature: data.signature,
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
]
});
}
});
wx.ready(function(){
var shareData = {
title: '1111111', // 分享标题
desc: '111111', // 分享描述
link: location.hostname+location.pathname,
imgUrl: '11111'
};
wx.onMenuShareAppMessage(shareData);
wx.onMenuShareTimeline(shareData);
});
});

获得access_token和jsapi_ticket有必要的可缓存一下,个人建议这样,大概这样可以实现微信分享了,其实这样js-sdk中所有的函数都可以使用了,其实很简单的,又不明白的可以联系qq:980527632; 要源码的留邮箱

因索要源码人数过多,来不及发送,故附上百度云盘资源:http://pan.baidu.com/s/1sj5JUVF

js-sdk探索之微信网页分享的更多相关文章

  1. 转:js-sdk探索之微信网页分享

    原文地址 微信是一个很不错的传播平台,最近公司需要做一个新年贺卡,使用html5制作一个很小的动画,然后发送给客户,不需要和后台有任何的联系,一个很简单的功能,需要利用微信的分享功能,毕竟微信分享的带 ...

  2. 微信JS SDK配置授权,实现分享接口

    微信开放的JS-SDK面向网页开发者提供了基于微信内的网页开发工具包,最直接的好处就是我们可以使用微信分享.扫一扫.卡券.支付等微信特有的能力.7月份的时候,因为这个分享的证书获取问题深深的栽了一坑, ...

  3. 微信网页分享使用了jssdk,分享图还是不显示的几个坑

    坑爹的微信分享,设置图片链接必须要满足如下条件: 1. 微信分享图链接必须是绝对路径,写相对地址不行. 比如图片地址写成 './assets/images/share.jpg' 不行!!! 必须写成 ...

  4. 微信网页分享 jssdk config:invalid signature 签名错误

    invalid signature签名错误.建议按如下顺序检查: 确认签名算法正确,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisi ...

  5. 实战微信JS SDK开发:贺卡制作与播放(1)

    前段时间忙于CanTK 2.0的开发,所以博客一直没有更新.CanTK 2.0主要增强了游戏和富媒体的开发,现在编码和测试基本完成了,等文档完成了再正式发布,里面有不少激动人心的功能,等发布时再一一细 ...

  6. 微信网页JS分享,微信二次分享无缩略图问题

    很多时候我们要在微信中分享h5网页,这个时候就得用微信的分享接口来自定义分享的地址.标题.描述.缩略图了. 分享到微信的时候遇到一个问题,就是第一次分享到微信里,是正确的,但是在微信打开分享的链接,再 ...

  7. 微信JS SDK接入的几点注意事项

    微信JS SDK接入,主要可以先参考官网说明文档,总结起来有几个步骤: 1.绑定域名:先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”.备注:登录后可在“开发者中心”查看对 ...

  8. VueJs单页应用实现微信网页授权及微信分享功能

    在实际开发中,无论是做PC端.WebApp端还是微信公众号等类型的项目的时候,或多或少都会涉及到微信相关的开发,最近公司项目要求实现微信网页授权,并获取微信用户基本信息的功能及微信分享的功能,现在总算 ...

  9. 微信JS SDK Demo

    微信JS-SDK 分享到朋友圈 分享给朋友 分享到QQ 拍照或从手机相册中选图 识别音频并返回识别结果 使用微信内置地图查看位置原文:http://www.cnblogs.com/txw1958/p/ ...

随机推荐

  1. HDU 1231 最大连续子序列 &&HDU 1003Max Sum (区间dp问题)

    C - 最大连续子序列 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit ...

  2. android设置图片自适应控件大小

    在XML文件的ImageView属性中加上:android:scaleType="fitXY"

  3. emu1

    第一题 一个很奇怪的贪心.先排序一遍,再扫描一遍,能加入尽量加入,不能加入就一定不能加入..由于每次都在可能的最早时间加入一个数可以保证差最小?反正差不多这样了. O(n log n) #includ ...

  4. 获取oracle 表字段,表名,以及主键之类等等的信息。

    获取表名:  Oracle的user_talbes用于记录了用户表信息. select * from user_tables  获取某个表的字段: USER_TAB_COLS中记录了用户表的列信息.下 ...

  5. 一段功能齐全的PHP常用重定向代码html+js+header

    /** * 重定向浏览器到指定的 URL * * @param string $url 要重定向的 url * @param int $delay 等待多少秒以后跳转 * @param bool $j ...

  6. A + B Problem

    Write a function that add two numbers A and B. You should not use + or any arithmetic operators. 分析: ...

  7. Android ViewPager轮播图

    Android客户端开发中很多时候需要用到轮播图的方式进行重点新闻的推送或者欢迎页面的制作,下面这个轮播图效果的Deamo来自互联网再经过修改而成. 1.布局文件activity_main.xml中添 ...

  8. Android Fragment间对象传递

    由于Activity相对较为笨重,因而在日常的开发中很多时候会用到Fragment.然而Activity之间是通过Intent进行数据的传递,那Fragment是通过什么来进行传递的呢?Fragmen ...

  9. (转)SQL SERVER的锁机制(四)——概述(各种事务隔离级别发生的影响)

    六.各种事务隔离级别发生的影响 修改数据的用户会影响同时读取或修改相同数据的其他用户.即这些用户可以并发访问数据.如果数据存储系统没有并发控制,则用户可能会看到以下负面影响: · 未提交的依赖关系(脏 ...

  10. Java最常用的变量定义汇总

    Java最常用的数据类型有基本数据类型,字符串对象,数组,基本数据类型又分为:数值型(包括整形和浮点型),字符型,布尔型,下面用一个简单的程序把这些数据类型汇总一下 public class Java ...