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

本人自己寫完全棧小項目,想在微信分享時帶標(biāo)題、描述和縮略圖,沒想到搞了3天,才搞定!所以寫篇文章,記錄浪費的時間,以此為戒,以后要多讀書。。。

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

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

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


在這個位置處,填寫js安全域名


上傳到域名根目錄后,一定要檢查能否訪問


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


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



同時要去接口權(quán)限內(nèi),檢查公眾號是否有分享權(quán)限,我之前找了一個沒有權(quán)限的公眾號號,被坑了半個小時。

二、動手實踐

1、后端代碼

/getwe 這個接口是用來,接受微信服務(wù)器驗證的;/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);

? ? /*? 加密/校驗流程如下: */

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

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

? ? array.sort();

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

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

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

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

? ? //3. 開發(fā)者獲得加密后的字符串可與signature對比,標(biāo)識該請求來源于微信

? ? 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: "",// 微信公眾號ID

? ? ? ? appSecret: "" //微信公眾號里有

? ? },

? ? configEnd = {

? ? ? ? appID: '',

? ? ? ? access_token: '',

? ? ? ? ticket: '',

? ? ? ? timestamp: '', // 必填,生成簽名的時間戳

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

? ? ? ? signature: '', // 必填,簽名,見附錄1

? ? };

/**

* 微信分享

*/

class wxShare {

? ? /**

? ? * 請求獲取access_token 方法入口

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

? ? * @param {* 回調(diào)請求方法} 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)請求方法} 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(); // 時間戳

? ? ? ? ? ? ? ? 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);

? ? };

? ? /**

? ? * 時間戳

? ? */

? ? 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、前端代碼

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

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

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模式的時候 獲取錨點之前的鏈接
??? 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] // 獲取錨點之前的鏈接

??? // 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īng)的公眾號JS安全域名一致
??????? imgUrl: icon, // 分享圖標(biāo)
??????? success: function() {
????????? // 設(shè)置成功
????????? console.log('設(shè)置成功')
??????? }
????? })
????? // 微信分享菜單測試
????? wx.onMenuShareTimeline({
??????? title: title, // 分享標(biāo)題
??????? link: links, // 分享鏈接,該鏈接域名或路徑必須與當(dāng)前頁面對應(yīng)的公眾號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è)置寫的明明白白 https://github.com/SevenChen/VueWxShare

后臺部分借鑒了 https://blog.csdn.net/baidu_31333625/article/details/72673958

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 先引入JS 文件 this.wxShare() 在created里調(diào)用 首先登陸微信公眾號 JSSDK使用步驟 步...
    寄魚予海與你閱讀 6,954評論 1 3
  • 久違的新文章發(fā)布。。我的鍋這篇文章是在寫的太長,可以慢慢看一下,偽代碼,畢竟簡書上面,望大家見諒!??!先看官方文檔...
    wyatt_plus閱讀 1,710評論 0 2
  • 人生總是奇妙的, 一旦你努力去做一件事, 即便這件事聽起來就像癡人說夢, 也一定會有開花結(jié)果的那一天。 也許結(jié)果不...
    凈含量cy閱讀 270評論 0 0
  • “嘀!” 清脆的水滴聲響起。微弱的回音從四面八方反復(fù)回響,逐漸傳遍整條通道,隨即傳向籠罩在大片漆黑中的遠(yuǎn)方。 一點...
    生還者閱讀 572評論 1 13
  • 小說非原創(chuàng),作者不知。個人喜愛,供大家欣賞。 阿悔(二) 5、 想不到阿悔住在這么深的山里。 一路上傅秋抱怨不迭,...
    記號晴系閱讀 498評論 0 0

友情鏈接更多精彩內(nèi)容