如何通過接口實現動態二維碼的定時刷新
如何通過接口實現動態二維碼的定時刷新?
感覺本篇對你有幫助可以關注一下我的微信公眾號(深入淺出談java),會不定期更新知識和面試資料、技巧!!!

一、需求場景
在Web應用中,動態二維碼常用于以下場景:
- 登錄驗證:微信掃碼登錄、APP掃碼授權
- 支付場景:支付寶/微信支付碼定時刷新
- 票務系統:電子票二維碼防截屏盜用
- 會員系統:動態會員碼累計積分
二、技術方案設計
1、 整體流程

三、前端部分
大致流程
1、請求后端接口(按照現有項目格式即可)
2、后端接口的返回類型定義(byte[])
3、前端接收時定義響應類型(重點:responseType: 'arraybuffer')
4、對后端返回數據進行轉化:arrayBufferToBase64
5、對數據和標簽進行綁定
具體實現
1、獲取后端 二維碼 圖片接口
import {
generateMemberCode
} from '@/api/inter/member-code.js';
data() {
return {
codeImg: '',
timer: null, // 添加定時器引用,
}
},
onShow() {
// 立即加載一次
this.makeMemberCode();
// 設置定時器(注意保存引用)
this.timer = setInterval(() => {
this.makeMemberCode();
}, 30000);
},
onHide() {
// 頁面隱藏時清除定時器
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
},
methods: {
async makeMemberCode() {
const memberId = 1; // 使用假數據中的 id
const memberName = '張三'; // 使用假數據中的 nickname
const params = {
memberId,
memberName
};
try {
// 調用后端接口(這里可改成符合你項目的請求方式)
const response = await generateMemberCode(params);
console.log('完整響應:', response);
// 調試數據類型
console.log('響應數據類型:', typeof response);
// 處理二進制數據(適用于小程序)
if (typeof response === 'object' && response instanceof ArrayBuffer) {
const base64 = uni.arrayBufferToBase64(response);
this.codeImg = `data:image/png;base64,${base64}`;
console.log('新的 codeImg:', this.codeImg); // 調試輸出
} else if (typeof response.data === 'string') {
this.codeImg = `data:image/png;base64,${response.data}`;
}
// 處理URL
else if (response.data.imageUrl) {
this.codeImg = response.data.imageUrl;
}
} catch (error) {
console.error('請求失敗:', error);
uni.showToast({
title: '會員碼加載失敗',
icon: 'none'
});
}
}
}
上面部分用到的代碼: member-code.js
import { HttpClient } from '@/api/utils/request.js'; // 確保路徑正確
import api from '../../config/api.js'; // 導入 API 配置
const http = new HttpClient(api.base);
/**
* 獲取后端二維碼
*/
export async function generateMemberCode(params) {
try {
const response = await http.getbuffer('/api/wx/generate-qrcode',params);
console.log('Response:', response);
return response; // 返回響應數據
} catch (error) {
console.error('Error:', error);
throw error; // 繼續拋出錯誤以供上層處理
}
}
請求接口工具類:request.js
class HttpClient {
constructor(baseURL) {
this.baseURL = baseURL;
}
async getbuffer(url, params = {}) {
try {
//await this.checkTokenAndNavigate(); // 在發送請求前檢查 token
const queryString = this.buildQueryString(params);
const fullURL = `${this.baseURL}${url}${queryString}`;
return new Promise((resolve, reject) => {
uni.request({
url: fullURL,
method: 'GET',
header: {
'Content-Type': 'application/json',
'X-Auth-Token': `${uni.getStorageSync('token')}` // 如果需要在 header 中發送 token
},
responseType: 'arraybuffer', // 指定響應類型為 arraybuffer
success: (response) => {
resolve(response.data);
},
fail: (error) => {
console.error('GET request error:', error);
reject(error);
}
});
});
} catch (error) {
// 如果 checkTokenAndNavigate 拋出錯誤(例如沒有 token),則這里處理錯誤
return Promise.reject(error);
}
}
buildQueryString(params) {
if (!params || Object.keys(params).length === 0) {
return '';
}
return '?' + Object.keys(params)
.map(key => encodeURIComponent(key) + '=' + encodeURIComponent(params[key]))
.join('&');
}
}
export {
HttpClient
};
接口地址Api 配置類:API.js
// 生產環境
const prod = {
base: "http://XXXXXX:8099",
};
// 開發環境
const dev = {
base: "http://XXXXXXX:8099",
};
// 默認生產環境
let api = prod;
// 如果是開發環境
if (process.env.NODE_ENV === "development") {
api = dev;
}
// 微信小程序和App的打包方式建議為生產環境,所以這塊直接條件編譯賦值()
// #ifdef MP-WEIXIN || APP-PLUS
// 這個直接使用的是 dev 地址
api = dev;
// #endif
export default {
...api,
};
2、模板進行渲染
<view class="qrcode d-flex just-content-center align-items-center">
<image :src="`${codeImg}`" style="width: 350rpx; height: 350rpx;"></image>
</view>
四、后端部分
具體實現
1、添加依賴
<!-- ZXing Core and Java SE -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.1</version>
</dependency>
2、接口實現controller
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.ByteArrayOutputStream;
import java.nio.file.FileSystems;
import java.util.HashMap;
import java.util.Map;
@RestController
public class QRCodeController {
@GetMapping("/generate-qrcode")
public ResponseEntity<byte[]> generateQRCode(
@RequestParam String memberId,
@RequestParam String memberName) throws WriterException {
// 構建二維碼內容(內容可根據自己業務動態修改)
// 建議加上唯一標識,安全碼、起始時間、狀態等,保證二維碼安全性
String qrContent = "Member ID: " + memberId + ", Member Name: " + memberName;
// 設置二維碼參數
int width = 300;
int height = 300;
String imageFormat = "PNG"; // 圖片格式
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
// 生成二維碼
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode(qrContent, BarcodeFormat.QR_CODE, width, height, hints);
// 將二維碼寫入字節數組輸出流
ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix, imageFormat, pngOutputStream);
// 返回二維碼圖片
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
return new ResponseEntity<>(pngOutputStream.toByteArray(), headers, HttpStatus.OK);
}
}
接口測試
GET http://localhost:8080/generate-qrcode?memberId=12345&memberName=JohnDoe

前端處理后端的數據時,在一定要指定相應類型:responseType: 'arraybuffer'

五、效果展示

六、安全性設計
| 風險 | 防御方案 |
|---|---|
| 二維碼盜用 | 30秒短時效性 + 單次有效性驗證 |
| 接口暴力請求 | 限流策略(如Guava RateLimiter) |
| 中間人攻擊 | 全站HTTPS + 數據簽名 |
| XSS攻擊 | 前端輸入過濾 + CSP安全策略 |
七、總結
關鍵技術棧:
- 前端定時器 + 二進制流處理
- 后端二維碼生成 + 狀態管理
- 高效的緩存策略
最佳實踐建議:
- 始終為二維碼添加時效性和唯一性標識
- 敏感操作需二次確認(如掃碼后的授權確認)
- 監控二維碼使用率,優化生成策略
通過前后端協作,動態二維碼既能提升用戶體驗,又能有效保障系統安全性。
最后文章有啥不對,歡迎大佬在評論區指點!!!
如果感覺對你有幫助就點贊推薦或者關注一下吧!!!


浙公網安備 33010602011771號