后端圖片數據返回
后端通過二進制流的形式,寫入response中
controller層
/*** 獲取簽到二維碼*/@GetMapping("/sign-up-pict")public void signUpPict(Long id, Long semId, HttpServletResponse response) throws NoSuchAlgorithmException {signUpService.getImage(id, semId, response);}
service層
/*** 返回二維碼** @param id 教師id* @param semId 課程id* @param response* @return*/@Overridepublic void getImage(Long id, Long semId, HttpServletResponse response) throws NoSuchAlgorithmException {// 保存生成的二維碼圖片BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 業務邏輯, 全部忽略刪除了...// 設置返回數據類型response.setContentType("image/png");try {// 將圖片數據寫入out中OutputStream out = response.getOutputStream();// 將圖片數據寫入out中, 返回前端ImageIO.write(image, "png", out);out.close();}catch (IOException e) {throw new RRException(ErrorCode.IMAGE_GENERATE_FAILED);}}
前端axios接受數據
axios接受數據時,responseType 默認返回數據類型是 json,必須將其改為返回數據類型 blob。否則axois無法正確解析數據。
這里的http.request是對axios的封裝,把他當作axios用就行
return http.request<R<any>>("get",signModuleUrlApi(`/signup/sign-up-pict?id=${id}&semId=${semId}`),// 一定要加, 否則axios會把二進制數據處理為json{responseType: "blob"});
vue界面渲染
<template><!-- 忽略其它部分代碼, 下面這貨顯示圖片--><el-image :src="url" lazy />
<\template><script>const url = ref();// 發送請求signApi.signUpPict(id, semId.value).then(res => {const blob = new Blob([res], { type: "image/png" });// 創建URL對象url.value = URL.createObjectURL(blob);},error => {console.log(error);ElMessage.error("系統錯誤, 無法生成二維碼");});};
<\script>
注意事項
- 后端接口,最好不要有返回值,如果你設置了response.setContentType(“image/png”),很有可能在返回數據的時候出現序列化錯誤的bug
- 后端接口,最好對response的contentType設置一下,不然容易出現一些奇怪的bug
- 前端axios一定要設置responseType: “blob”,否則axios會把數據當成json處理
學習文章
https://zhuanlan.zhihu.com/p/474173086
https://www.jianshu.com/p/12fea9987c2d