vue + node + express 實(shí)現(xiàn)微信分享全攻略

本人自己寫(xiě)完全棧小項(xiàng)目序芦,想在微信分享時(shí)帶標(biāo)題臭杰、描述和縮略圖,沒(méi)想到搞了3天谚中,才搞定渴杆!所以寫(xiě)篇文章,記錄浪費(fèi)的時(shí)間宪塔,以此為戒磁奖,以后要多讀書(shū)。某筐。比搭。

技術(shù)棧:vue 2.9.2, node v8.11.1南誊, express 4.15.5

一身诺、前期準(zhǔn)備:

一定要看到微信的開(kāi)發(fā)者文檔,本人最后發(fā)現(xiàn)掉進(jìn)去的坑抄囚,都是開(kāi)發(fā)文檔沒(méi)看仔細(xì)霉赡。。


在這個(gè)位置處幔托,填寫(xiě)js安全域名


上傳到域名根目錄后穴亏,一定要檢查能否訪(fǎng)問(wèn)


在服務(wù)器配置里,后臺(tái)要寫(xiě)相應(yīng)的接口柑司,供微信調(diào)用迫肖,稍后上代碼。


要把服務(wù)器的ip地址添加到白名單里



同時(shí)要去接口權(quán)限內(nèi)攒驰,檢查公眾號(hào)是否有分享權(quán)限蟆湖,我之前找了一個(gè)沒(méi)有權(quán)限的公眾號(hào)號(hào),被坑了半個(gè)小時(shí)玻粪。

二隅津、動(dòng)手實(shí)踐

1诬垂、后端代碼

/getwe 這個(gè)接口是用來(lái),接受微信服務(wù)器驗(yàn)證的伦仍;/getsignature是供前端調(diào)用的接口结窘,可以獲取簽名等信息。

var express = require('express');

var crypto = require('crypto')

var router = express.Router();

var sha1 = require('sha1');

var wxShare = require('./wxShare')

var token = "403106220Asd"

/* GET home page. */

router.get('/getwe', function(req, res, next) {

? console.log();

? ? var signature = req.query.signature;

? ? var timestamp = req.query.timestamp;

? ? var nonce = req.query.nonce;

? ? var echostr = req.query.echostr;

? ? console.log(signature, timestamp, nonce, echostr);

? ? /*? 加密/校驗(yàn)流程如下: */

? ? //1. 將token充蓝、timestamp隧枫、nonce三個(gè)參數(shù)進(jìn)行字典序排序

? ? var array = new Array(token,timestamp,nonce);

? ? array.sort();

? ? var str = array.toString().replace(/,/g,"");

? ? //2. 將三個(gè)參數(shù)字符串拼接成一個(gè)字符串進(jìn)行sha1加密

? ? var sha1Code = crypto.createHash("sha1");

? ? var code = sha1Code.update(str,'utf-8').digest("hex");

? ? //3. 開(kāi)發(fā)者獲得加密后的字符串可與signature對(duì)比,標(biāo)識(shí)該請(qǐng)求來(lái)源于微信

? ? if(code===signature){

? ? ? ? res.send(echostr)

? ? }else{

? ? ? ? res.send("error");

? ? }

});

/**

* 分享

*/

router.post('/getsignature', function(req, res, next) {

? ? let hrefURL = req.body.urlhref;

? ? wxShare.prototype.accessToken(hrefURL, function(data) {

? ? ? ? res.json(data);

? ? });

});

module.exports = router;


wxShare:

var url = require('url');

var request = require('request');

var sha1 = require('sha1');

let config = {

? ? ? ? appID: "",// 微信公眾號(hào)ID

? ? ? ? appSecret: "" //微信公眾號(hào)里有

? ? },

? ? configEnd = {

? ? ? ? appID: '',

? ? ? ? access_token: '',

? ? ? ? ticket: '',

? ? ? ? timestamp: '', // 必填谓苟,生成簽名的時(shí)間戳

? ? ? ? nonceStr: '', // 必填官脓,生成簽名的隨機(jī)串

? ? ? ? signature: '', // 必填,簽名涝焙,見(jiàn)附錄1

? ? };

/**

* 微信分享

*/

class wxShare {

? ? /**

? ? * 請(qǐng)求獲取access_token 方法入口

? ? * @param {* URL鏈接} hrefURL

? ? * @param {* 回調(diào)請(qǐng)求方法} callback

? ? */

? ? accessToken(hrefURL, callback) { // 獲取access_token

? ? ? ? let _this = this;

? ? ? ? var tokenUrl = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' + config.appID + '&secret=' + config.appSecret;

? ? ? ? request(tokenUrl, function(error, response, body) {

? ? ? ? ? ? if (response.statusCode && response.statusCode === 200) {

? ? ? ? ? ? ? ? body = JSON.parse(body);

? ? ? ? ? ? ? ? configEnd.access_token = body.access_token;

? ? ? ? ? ? ? ? _this.upJsapiTicket(hrefURL, body.access_token, callback)

? ? ? ? ? ? }

? ? ? ? });

? ? };

? ? /**

? ? * 獲取Jsapi_Ticket

? ? * @param {* URL鏈接} hrefURL

? ? * @param {* token} access_Ttoken

? ? * @param {* 回調(diào)請(qǐng)求方法} callback

? ? */

? ? upJsapiTicket(hrefURL, access_Ttoken, callback) { // Jsapi_ticket

? ? ? ? let _this = this;

? ? ? ? var ticketUrl = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' + access_Ttoken + '&type=jsapi';

? ? ? ? request(ticketUrl, function(err, response, content) {

? ? ? ? ? ? content = JSON.parse(content);

? ? ? ? ? ? if (content.errcode == 0) {

? ? ? ? ? ? ? ? configEnd.appID = config.appID;

? ? ? ? ? ? ? ? configEnd.ticket = content.ticket; // ticket

? ? ? ? ? ? ? ? configEnd.timestamp = _this.createTimestamp(); // 時(shí)間戳

? ? ? ? ? ? ? ? configEnd.nonceStr = _this.createNonceStr(); // 隨機(jī)數(shù)

? ? ? ? ? ? ? ? configEnd.signature = _this.sign(hrefURL); // 簽名

? ? ? ? ? ? ? ? callback && callback(configEnd); // 回調(diào)前端JS方法

? ? ? ? ? ? }

? ? ? ? })

? ? };

? ? /**

? ? * 隨機(jī)字符串

? ? */

? ? createNonceStr() {

? ? ? ? return Math.random().toString(36).substr(2, 15);

? ? };

? ? /**

? ? * 時(shí)間戳

? ? */

? ? createTimestamp() {

? ? ? ? return parseInt(new Date().getTime() / 1000).toString();

? ? };

? ? /**

? ? * 拼接字符串

? ? * @param {*} args

? ? */

? ? rawString(args) {

? ? ? ? var keys = Object.keys(args);

? ? ? ? keys = keys.sort()

? ? ? ? var newArgs = {};

? ? ? ? keys.forEach(function(key) {

? ? ? ? ? ? newArgs[key.toLowerCase()] = args[key];

? ? ? ? });

? ? ? ? var string = '';

? ? ? ? for (var k in newArgs) {

? ? ? ? ? ? string += '&' + k + '=' + newArgs[k];

? ? ? ? }

? ? ? ? string = string.substr(1);

? ? ? ? return string;

? ? };

? ? /**

? ? * 簽名

? ? * @param {*} url

? ? */

? ? sign(url) {

? ? ? ? let _this = this;

? ? ? ? var ret = {

? ? ? ? ? ? jsapi_ticket: configEnd.ticket,

? ? ? ? ? ? nonceStr: configEnd.nonceStr,

? ? ? ? ? ? timestamp: configEnd.timestamp,

? ? ? ? ? ? url: url

? ? ? ? };

? ? ? ? var string = _this.rawString(ret);

? ? ? ? var shaObjs = sha1(string);

? ? ? ? return shaObjs;

? ? };

}

module.exports = wxShare;

2卑笨、前端代碼

在想要分享的頁(yè)面的mounted寫(xiě)上調(diào)用,同時(shí)引入已經(jīng)封裝好的js仑撞。

這里有個(gè)小坑就是赤兴,當(dāng)用npm i weixin-js-sdk? 在2019年2月17日下載的是1.40 test版本,可能不是很穩(wěn)定隧哮,在測(cè)試時(shí)候桶良,wx.config總是顯示錯(cuò)誤信息error massage “config ok”,最后發(fā)現(xiàn)目前開(kāi)發(fā)文檔推薦的updateAppMessageShareData和updateTimelineShareData根本返回不了數(shù)據(jù)沮翔,所以用以前版本的接口函數(shù)艺普,就通過(guò)了。

import wxshare from '@/utils/wxshare'

export default {

? data() {

? ? return {

? ? ? // jsonurl: ''

? ? }

? },

? // created() {

? //? // console.log('self.router', this.$route)

? //? this.jsonurl = this.$route.query

? // },

? mounted() {

? ? wxshare.do(this.$route.query, '縮略圖url', '想用的標(biāo)題', '這是一段描述')

? }


wxshare:

import axios from 'axios'
import wx from 'weixin-js-sdk'

const wxshare = {
? do(queryId, icon = '', title = '', desc = '') {
??? const url = location.href.split('#')[0] // ruoter是hash模式的時(shí)候 獲取錨點(diǎn)之前的鏈接
??? console.log('前端傳輸前的url地址', location.href)
??? console.log('前端傳輸前的url地址', url)
??? axios.post('https:/..../getsignature', { // 服務(wù)端獲取配置jssdk 簽名等 文件

????? urlhref: url

??? }).then(response => {
????? const res = response.data
????? console.log('調(diào)用微信js接口返回的簽名:', res)

????? this.wxInit(res, queryId, icon, title, desc)
??? })
? },
? // 微信分享
? wxInit(res, queryId, icon = '', title = '', desc = '') {
??? const url = location.href.split('#')[0] // 獲取錨點(diǎn)之前的鏈接

??? // let links = url+'#/Food/' + this.$route.params.id;??? //用于簽名的url 和 用于微信分享的url可以不同
??? // const links = url + '#/?jsonurl=' + queryId

??? const links = url

??? console.log('url link:', links)

??? wx.config({
????? debug: false,
????? appId: res.appID,
????? timestamp: res.timestamp,
????? nonceStr: res.nonceStr,
????? signature: res.signature,
????? jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline']
??? })
??? wx.ready(function() {
????? wx.onMenuShareAppMessage({
??????? title: title, // 分享標(biāo)題
??????? desc: desc, // 分享描述
??????? link: links, // 分享鏈接鉴竭,該鏈接域名或路徑必須與當(dāng)前頁(yè)面對(duì)應(yīng)的公眾號(hào)JS安全域名一致
??????? imgUrl: icon, // 分享圖標(biāo)
??????? success: function() {
????????? // 設(shè)置成功
????????? console.log('設(shè)置成功')
??????? }
????? })
????? // 微信分享菜單測(cè)試
????? wx.onMenuShareTimeline({
??????? title: title, // 分享標(biāo)題
??????? link: links, // 分享鏈接,該鏈接域名或路徑必須與當(dāng)前頁(yè)面對(duì)應(yīng)的公眾號(hào)JS安全域名一致
??????? imgUrl: icon, // 分享圖標(biāo)
??????? success: function() {
????????? // 設(shè)置成功
????????? console.log('設(shè)置成功')
??????? }
????? })
??? })
??? wx.error(function(err) {
????? alert(JSON.stringify(err))
??? })
? }
}

export default wxshare

PS:本人此次也是站在了巨人的肩膀上岸浑,所以避免了二次分享的坑搏存、router是否是history的坑……如可以更優(yōu)化代碼地方,可以指正矢洲,共同進(jìn)步璧眠!

文末奉上友情鏈接:

這位大神已經(jīng)把vue前端如何設(shè)置寫(xiě)的明明白白 https://github.com/SevenChen/VueWxShare

后臺(tái)部分借鑒了 https://blog.csdn.net/baidu_31333625/article/details/72673958

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市读虏,隨后出現(xiàn)的幾起案子责静,更是在濱河造成了極大的恐慌,老刑警劉巖盖桥,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灾螃,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡揩徊,警方通過(guò)查閱死者的電腦和手機(jī)腰鬼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)嵌赠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人熄赡,你說(shuō)我怎么就攤上這事姜挺。” “怎么了彼硫?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵炊豪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我拧篮,道長(zhǎng)词渤,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任他托,我火速辦了婚禮掖肋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赏参。我一直安慰自己志笼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布把篓。 她就那樣靜靜地躺著纫溃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪韧掩。 梳的紋絲不亂的頭發(fā)上紊浩,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音疗锐,去河邊找鬼坊谁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛滑臊,可吹牛的內(nèi)容都是我干的口芍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼雇卷,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼鬓椭!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起关划,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤小染,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后贮折,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體裤翩,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年调榄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了岛都。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片律姨。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖臼疫,靈堂內(nèi)的尸體忽然破棺而出择份,到底是詐尸還是另有隱情,我是刑警寧澤烫堤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布荣赶,位于F島的核電站,受9級(jí)特大地震影響鸽斟,放射性物質(zhì)發(fā)生泄漏拔创。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一富蓄、第九天 我趴在偏房一處隱蔽的房頂上張望剩燥。 院中可真熱鬧,春花似錦立倍、人聲如沸灭红。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)变擒。三九已至,卻和暖如春寝志,著一層夾襖步出監(jiān)牢的瞬間娇斑,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工材部, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留毫缆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓乐导,卻偏偏與公主長(zhǎng)得像悔醋,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子兽叮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 先引入JS 文件 this.wxShare() 在created里調(diào)用 首先登陸微信公眾號(hào) JSSDK使用步驟 步...
    寄魚(yú)予海與你閱讀 6,697評(píng)論 1 3
  • 久違的新文章發(fā)布。猾愿。我的鍋這篇文章是在寫(xiě)的太長(zhǎng)鹦聪,可以慢慢看一下,偽代碼蒂秘,畢竟簡(jiǎn)書(shū)上面泽本,望大家見(jiàn)諒!R錾规丽!先看官方文檔...
    wyatt_plus閱讀 1,638評(píng)論 0 2
  • 人生總是奇妙的蒲牧, 一旦你努力去做一件事, 即便這件事聽(tīng)起來(lái)就像癡人說(shuō)夢(mèng)赌莺, 也一定會(huì)有開(kāi)花結(jié)果的那一天冰抢。 也許結(jié)果不...
    凈含量cy閱讀 227評(píng)論 0 0
  • “嘀!” 清脆的水滴聲響起艘狭。微弱的回音從四面八方反復(fù)回響挎扰,逐漸傳遍整條通道,隨即傳向籠罩在大片漆黑中的遠(yuǎn)方巢音。 一點(diǎn)...
    生還者閱讀 506評(píng)論 1 12
  • 小說(shuō)非原創(chuàng)遵倦,作者不知。個(gè)人喜愛(ài)官撼,供大家欣賞梧躺。 阿悔(二) 5、 想不到阿悔住在這么深的山里傲绣。 一路上傅秋抱怨不迭掠哥,...
    記號(hào)晴系閱讀 438評(píng)論 0 0