<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      如何通過接口實現動態二維碼的定時刷新

      如何通過接口實現動態二維碼的定時刷新?

      感覺本篇對你有幫助可以關注一下我的微信公眾號(深入淺出談java),會不定期更新知識和面試資料、技巧!!!

      一、需求場景

      在Web應用中,動態二維碼常用于以下場景:

      1. 登錄驗證:微信掃碼登錄、APP掃碼授權
      2. 支付場景:支付寶/微信支付碼定時刷新
      3. 票務系統:電子票二維碼防截屏盜用
      4. 會員系統:動態會員碼累計積分

      二、技術方案設計

      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安全策略

      七、總結

      關鍵技術棧

      • 前端定時器 + 二進制流處理
      • 后端二維碼生成 + 狀態管理
      • 高效的緩存策略

      最佳實踐建議

      1. 始終為二維碼添加時效性和唯一性標識
      2. 敏感操作需二次確認(如掃碼后的授權確認)
      3. 監控二維碼使用率,優化生成策略

      通過前后端協作,動態二維碼既能提升用戶體驗,又能有效保障系統安全性。

      最后文章有啥不對,歡迎大佬在評論區指點!!!
      如果感覺對你有幫助就點贊推薦或者關注一下吧!!!
      img

      posted @ 2025-05-26 16:57  古渡藍按  閱讀(686)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 人人做人人妻人人精| 精品无码国产污污污免费| 中文字幕无码成人免费视频| 久久精品人妻无码专区| 亚洲中文字幕在线观看| 亚洲精品国产综合久久一线| 四虎国产精品成人免费久久| 久久天天躁狠狠躁夜夜2020老熟妇| a4yy私人毛片| 天祝| 国产精品自产拍在线播放| 久久精品国产99国产精品严洲 | 亚洲AV无码久久精品成人| 亚洲精品自拍视频在线看| 色欲久久久天天天综合网| 亚洲精品三区四区成人少| 美女爽到高潮嗷嗷嗷叫免费网站| 久久免费偷拍视频有没有| 民权县| 亚洲欧美日韩高清一区二区三区| 狠狠综合久久综合88亚洲爱文| 国产成人亚洲精品青草天美| 亚洲鸥美日韩精品久久| 国产360激情盗摄全集| 国内揄拍国内精品人妻久久 | 激情综合网址| 无码日韩做暖暖大全免费不卡| 色综合久久精品中文字幕| 国产自产av一区二区三区性色| 亚洲免费成人av一区| 黄网站色视频免费观看| 无码天堂亚洲国产av麻豆| 四虎女优在线视频免费看| 亚洲国产精品久久久久4婷婷| a男人的天堂久久a毛片| 91亚洲国产成人久久精品| 内射极品少妇xxxxxhd| 无码专区人妻系列日韩精品少妇| 99精品久久毛片a片| 成人午夜污一区二区三区| 国产亚洲精品成人aa片新蒲金|