微信小程式之生成自定義引數小程式二維碼
掃碼已經成為一種常見又方便的進入移動應用的途徑,可以把線上線下的使用者流量帶入你的移動應用中來。微信小程式也提供了掃碼進入的功能,可以通過掃描二維碼或者微信小程式專有的小程式碼,進入到相應的小程式頁面。
微信官方提供了3個不同的REST API用於生成帶引數的小程式碼或者二維碼,可在掃碼後進入指定的小程式頁面,其中介面A和C能生成的圖片總數量有限制(10萬張),對於那種需要生成大量二維碼的使用場景(比如為每個訂單生成一個二維碼、餐廳的每張餐桌生成一個二維碼等)是遠遠不能滿足需求的。而介面B可以解決這個問題,我們這次主要來看一下如何使用這個介面。
總體的思路是:在我們的後端開發一個API,在其中呼叫微信的二維碼介面,呼叫成功後會得到二維碼圖片的二進位制流,最後將這個二進位制流輸出到前臺。
以下步驟中的後端程式碼是基於Node.js進行編寫,並使用了Koa 2框架。程式碼僅供參考。
步驟1:獲取重要引數access_token
呼叫獲取小程式二維碼的REST API需要一個很重要的引數:access_token
,這是用於獲取微信公眾平臺API訪問許可權的重要引數,做過微信公眾號HTML5開發的朋友對其肯定非常熟悉。沒接觸過的話,可以看一下微信公眾平臺的文件。
呼叫微信公眾平臺的API,已經有很多成熟的開源SDK可以使用,從Github上可以搜到很多不同語言實現的SDK。由於我用的是Node.js開發,所以使用了co-wechat-api。
以下是使用co-wechat-api
access_token
的基本用法:
const WechatAPI = require('co-wechat-api')
const wxAppAPI = new WechatAPI('小程式的app id', '小程式的app secret')
const token = await wxAppAPI.ensureAccessToken()
console.log(token.accessToken)
步驟2:拼接url,傳送請求獲取二維碼圖片
const fs = require('fs') const axios = require('axios') // 拼接url const url = `https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=${token.accessToken}` // 傳送POST請求 const response = await axios.post(url, { page: '小程式中Page的路徑', scene: '自定義引數,格式你自己決定' }, { responseType: 'stream' }) // 將請求結果中的二進位制流寫入到本地檔案qrcode.png response.data.pipe(fs.createWriteStream('qrcode.png'))
在上面的程式碼中,我們將access_token
作為query string引數拼接到url上,然後向這個url傳送POST
請求,傳遞的引數主要是page
和scene
,其中page
引數是掃碼後進入的小程式頁面路徑(比如pages/index/index,並且不能攜帶引數),而scene
則傳入的是我們的自定義引數。
其實經過這一步,你就已經可以在你的磁碟上找到這張小程式碼的圖片了,用微信掃一下這張圖片,就能進入你的小程式頁面。
步驟3:將二維碼圖片輸出
雖然我們已經獲取到了小程式碼圖片,但是現在它還只是躺在我們的伺服器端。而通常實際情況是,我們需要在小程式頁面上去顯示這張圖片,讓使用者去儲存和分享它。因此,我們需要把這張圖片通過我們的API進行輸出。以下是基於koa 2的示例程式碼:
const fs = require('fs')
const Router = require('koa-router')
const router = new Router()
router.get('/wx/common/qrcode', async (ctx) => {
const stream = fs.createReadStream(‘qrcode.png’)
ctx.body = stream
})
步驟4:在小程式中顯示
在小程式中顯示該圖片就非常簡單了,直接使用<image>
元件來進行展示:
<image src="https://your-domain.com/wx/common/qrcode" style="width:200px;height:200px"></image>
附錄:稍微完備一些的服務端程式碼
上面4個步驟中給出的示例程式碼只是為了配合說明各個步驟,程式碼比較簡陋,下面是經過稍微的組織過的程式碼,供參考:
- 路由部分的程式碼:
const Router = require('koa-router')
const PassThrough = require('stream').PassThrough;
const wxapi = require('../services/wxapi')
const router = new Router()
router.get('/wx/common/qrcode', async (ctx) => {
const stream = await wxapi.getWxaCodeUnlimit({
page: 'pages/profile/profile',
scene: 'abc123'
})
ctx.body = stream.pipe(PassThrough())
})
- Service部分的程式碼:
const fs = require('fs')
const path = require('path')
const crypto = require('crypto')
const bluebird = require('bluebird')
const axios = require('axios')
const WechatAPI = require('co-wechat-api')
const wxAppAPI = new WechatAPI('小程式的app id', '小程式的app secret')
function sha1(message) {
return crypto.createHash('sha1').update(message, 'utf8').digest('hex')
}
module.exports = {
async getWxaCodeUnlimit({ page, scene }) {
// 圖片檔名使用page和scene等資料生成Hash
// 以避免重複生成內容相同的小程式碼
const fileName = sha1(page + scene)
const filePath = path.join(__dirname, `../../qrcode/${fileName}.png`)
let readable
try {
// 檢測該名字的小程式碼圖片檔案是否已存在
await bluebird.promisify(fs.access)(filePath, fs.constants.R_OK);
readable = fs.createReadStream(filePath)
} catch (e) {
// 小程式碼不存在,則建立一張新的
const token = await wxAppAPI.ensureAccessToken()
const response = await axios({
method: 'post',
url: 'https://api.weixin.qq.com/wxa/getwxacodeunlimit',
responseType: 'stream',
params: { access_token: token.accessToken },
data: { page, scene }
})
readable = response.data
readable.pipe(fs.createWriteStream(filePath))
}
// 返回該小程式碼圖片的檔案流
return readable
}
}
祝大家開發出更好的小程式!
作者:一斤程式碼
連結:https://www.jianshu.com/p/3056754987e8
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。