分享

微信分享带缩略图和简介 实现静态文件使用JSSDK静态JS接口

发布于:2019-08-27 19:30    阅读次数:124    作者:云码素材    分类:行业经验    关键词:微信分享  

在网上找了一圈,参考了一篇使用静态页面ajax调用php接口的方法,因为有多个网址展示同一篇不知谁才是原始作者,我就不贴出处了。将其改造了下,接口分成两个文件,一个jssdk.php用于后端生成凭证缓存,一个jssdk.js用于静态页面调用。


环境与需求:

0、前提条件,需要有个微信公众号;通过

微信JS-SDK使用参考官方说明文档 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

1、实现微信分享静态网页到朋友圈/好友,可定义标题、缩略图和简介;

2、服务器环境分前后端,前端带防篡改,需要在后端生成缓存而非前端(会被防篡改系统删除);

3、为方便子域名调用且为了更安全,接口最好是静态的。


基于以上的环境与需求,主要思路:

0、假设接口文件都放在/api/目录下,html可在任何目录下。

1、后端服务器通过计划任务运行PHP文件(jssdk.php)定时生成接口缓存(因接口调用次数极其有限,文档要求必须在自己的服务器缓存access_token与jsapi_ticket,凭证有效期7200秒,推荐3600-7000秒之间生成一次),缓存文件自动同步到前端;

2、前端静态页面利用JS+jQuery调用接口(jssdk.js)读取有效的凭证缓存,实现分享;


备注:其实jssdk.php已经是一个完整的接口文件,可生成缓存也可直接静态文件调用,但对于访问量较大的网站,分离一个简单的js接口会更节省资源;jssdk.php和jssdk.js里需要填入公众号相关资料。

一.test.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>分享测试</title>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
</head>
<body>
</body>

<script>
var shareData = {
title: '标题',
desc: '简介',
link: "http://www.test.com/test.html",
imgUrl: 'http://www.test.com/images/wechat.jpg'
};
</script>

<script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<script src="/api/jssdk.js"></script>
</html>

二.jssdk.js

$(function (){
	$.getJSON("/api/jsapi_ticket.json", function (data){
		var jsapiTicket = data["jsapi_ticket"];

		// 时间戳
		var timestamp = Date.parse( new Date() ).toString();
		timestamp = timestamp.substr(0,10);

		// 随机字符串
		var nonceStr = randomWord(false, 16);

		// 当前网址
		var url1=window.location.href.split('#')[0];

		// 生成签名
		var string1 = "jsapi_ticket="+jsapiTicket+"&noncestr="+nonceStr+"&"+"timestamp="+timestamp+"&url="+url1;
		var signature = SHA2(string1);

		wx.config({
			debug: false,
			appId: '公众号ID', // 在这里填入公众号ID
			timestamp: timestamp,
			nonceStr: nonceStr,
			signature: signature,
			jsApiList: [
				//'updateAppMessageShareData',
				//'updateTimelineShareData',
				'onMenuShareTimeline',
				'onMenuShareAppMessage',
				'onMenuShareQQ',
				'onMenuShareWeibo',
				'onMenuShareQZone',
			]
		});

	})
})


wx.ready(function (){
	//wx.updateAppMessageShareData(shareData);
	//wx.updateTimelineShareData(shareData);
	wx.onMenuShareAppMessage(shareData);
	wx.onMenuShareTimeline(shareData);
	wx.onMenuShareQQ(shareData);
	wx.onMenuShareWeibo(shareData);
});



/* ---------------------------------------------------------------------------*/
// 以下是所需用到的随机函数和SHA1函数

// 随机函数
function randomWord(randomFlag, min, max){
	var str = "",
	range = min,
	arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 
	'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 
	'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
	 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
	// 随机产生
	if(randomFlag){
		range = Math.round(Math.random() * (max-min)) + min;
	}
	for(var i=0; i<range; i++){
		pos = Math.round(Math.random() * (arr.length-1));
		str += arr[pos];
	}
	return str;
}


/* ---------------------------------------------------------------------------*/

// SHA1
function add(x, y) {
	return((x & 0x7FFFFFFF) + (y & 0x7FFFFFFF)) ^ (x & 0x80000000) ^ (y & 0x80000000);
}

function SHA1hex(num) {
	var sHEXChars = "0123456789abcdef";
	var str = "";
	for(var j = 7; j >= 0; j--)
		str += sHEXChars.charAt((num >> (j * 4)) & 0x0F);
	return str;
}

function AlignSHA1(sIn) {
	var nblk = ((sIn.length + 8) >> 6) + 1,
		blks = new Array(nblk * 16);
	for(var i = 0; i < nblk * 16; i++) blks[i] = 0;
	for(i = 0; i < sIn.length; i++)
		blks[i >> 2] |= sIn.charCodeAt(i) << (24 - (i & 3) * 8);
	blks[i >> 2] |= 0x80 << (24 - (i & 3) * 8);
	blks[nblk * 16 - 1] = sIn.length * 8;
	return blks;
}

function rol(num, cnt) {
	return(num << cnt) | (num >>> (32 - cnt));
}

function ft(t, b, c, d) {
	if(t < 20) return(b & c) | ((~b) & d);
	if(t < 40) return b ^ c ^ d;
	if(t < 60) return(b & c) | (b & d) | (c & d);
	return b ^ c ^ d;
}

function kt(t) {
	return(t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
		(t < 60) ? -1894007588 : -899497514;
}

function SHA1(sIn) {
	var x = AlignSHA1(sIn);
	var w = new Array(80);
	var a = 1732584193;
	var b = -271733879;
	var c = -1732584194;
	var d = 271733878;
	var e = -1009589776;
	for(var i = 0; i < x.length; i += 16) {
		var olda = a;
		var oldb = b;
		var oldc = c;
		var oldd = d;
		var olde = e;
		for(var j = 0; j < 80; j++) {
			if(j < 16) w[j] = x[i + j];
			else w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
			t = add(add(rol(a, 5), ft(j, b, c, d)), add(add(e, w[j]), kt(j)));
			e = d;
			d = c;
			c = rol(b, 30);
			b = a;
			a = t;
		}
		a = add(a, olda);
		b = add(b, oldb);
		c = add(c, oldc);
		d = add(d, oldd);
		e = add(e, olde);
	}
	SHA1Value = SHA1hex(a) + SHA1hex(b) + SHA1hex(c) + SHA1hex(d) + SHA1hex(e);
	return SHA1Value.toUpperCase();
}

function SHA2(sIn) {
	return SHA1(sIn).toLowerCase();
}

三.jssdk.php

<?php

$url = '';

class JSSDK {
	private $appId;
	private $appSecret;
	private $url;
	public function __construct($appId, $appSecret,$url) {
		$this->appId = $appId;
		$this->appSecret = $appSecret;
		$this->url = $url;
	}

	public function getSignPackage() {
		$jsapiTicket = $this->getJsApiTicket();
		//$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || 
		$_SERVER['SERVER_PORT'] == 443)? "https://" : "http://";
		// $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
		$url =$this->url;
		$timestamp = time();
		$nonceStr = $this->createNonceStr();

		// 这里参数的顺序要按照 key 值 ASCII 码升序排序
		$string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
		$signature = sha1($string);
		$signPackage = array(
			"appId"			=> $this->appId,
			"nonceStr"	=> $nonceStr,
			"timestamp"	=> $timestamp,
			"url"				=> $url,
			"signature"	=> $signature,
			"rawString"	=> $string
		);
		return $signPackage;
	}

	private function createNonceStr($length = 16) {
		$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		$str = "";
		for ($i = 0; $i < $length; $i++) {
			$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
		}
		return $str;
	}

	private function getJsApiTicket() {
		// jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例
		$data = json_decode(file_get_contents("jsapi_ticket.json"));
		if ($data->expire_time < time()) {
			$accessToken = $this->getAccessToken();
			// 如果是企业号用以下 URL 获取 ticket
			//$url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
			$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
			$res = json_decode($this->httpGet($url));
			$ticket = $res->ticket;

			if ($ticket) {
				$data->expire_time = time() + 3600;
				$data->jsapi_ticket = $ticket;
				$fp = fopen("jsapi_ticket.json", "w");
				fwrite($fp, json_encode($data));
				fclose($fp);
			}

		} else {
			$ticket = $data->jsapi_ticket;
		}

		return $ticket;
	}

	private function getAccessToken() {
		// access_token 应该全局存储与更新,以下代码以写入到文件中做示例
		$data = json_decode(file_get_contents("access_token.json"));
		if ($data->expire_time < time()) {
			// 如果是企业号用以下URL获取access_token
			// $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=
			$this->appId&corpsecret=$this->appSecret";
			$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=
			$this->appId&secret=$this->appSecret";
			$res = json_decode($this->httpGet($url));
			$access_token = $res->access_token;

			if ($access_token) {
				$data->expire_time = time() + 3600;
				$data->access_token = $access_token;
				$fp = fopen("access_token.json", "w");
				fwrite($fp, json_encode($data));
				fclose($fp);
			}

		} else {
			$access_token = $data->access_token;
		}
		return $access_token;
	}

	private function httpGet($url) {
		$curl = curl_init();
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($curl, CURLOPT_TIMEOUT, 500);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($curl, CURLOPT_URL, $url);
		$res = curl_exec($curl);
		curl_close($curl);
		return $res;
	}
}

$jssdk = new JSSDK("公众号ID", "公众号密钥",$url);
$signPackage = $jssdk->GetSignPackage();
$tmp=json_encode(array ('appId'=>$signPackage["appId"],'timestamp'=>$signPackage["timestamp"],
'nonceStr'=>$signPackage["nonceStr"],'signature'=>$signPackage["signature"],'url'=>$signPackage["url"]));
$callback = $_GET['callback'];
echo $callback.'('.$tmp.')';
exit;
?>


推荐源码
查看更多

免费领
签到客服赚钱 反馈 回顶部