使用场景: 使用传统的img标签查看图片无法添加header,但是后台接口需要头部携带token进行验证。这样的话可以使用axios携带header发起请求,让后台传给前端一个图片二进制流,在前端接收并转成base64的形式展示。
我这里是使用vue-element-template模板进行二次开发的,所以代码模块化程度比较高,具体实现根据自己情况。
模板封装了axios的请求,统一做了添加请求头的处理,这个也可以直接在axios config里面加上。
好现在开始写:
首先是api,注意responseType,设置响应类型为二进制流:
export function getAvatar(params) {
return request({
url: '/api/sys/user/avatar',
method: 'post',
responseType: 'arraybuffer',
params
})
}
在需要加载图片的地方调用上面的api,我这里是要传入一个文件名的参数,后台需要:
getAvatar({ 'localPath': localPath }).then(function(response) {
// 将后台的图片二进制流传华为base64
return 'data:image/png;base64,' + btoa(
new Uint8Array(response).reduce((data, byte) => data + String.fromCharCode(byte), '')
)
}).then(data => {
this.imgUrl = data // data即为图片地址
})
这样imgUrl就是base64编码的很长的字符串了,像这样:
在使用图片的地方进行绑定即可显示:
<img :src="imgUrl" class="user-avatar">
后端代码:
@ApiOperation("获取用户头像文件流")
@ApiImplicitParams({
@ApiImplicitParam(name = "localPath", value = "头像文件本地路径", required = true)})
@PostMapping(value = "avatar")
public void avatar(@RequestParam("localPath") String localPath, HttpServletResponse response) throws Exception {
String filename = localPath.split("/")[1];
File file = fileSystemService.downloadFile(localPath);
FileInputStream fis = new FileInputStream(file);
byte[] bytes = IOUtils.toByteArray(fis);
response.reset();
response.setHeader("Content-Disposition", "attachment;filename=" + filename);
//文件下载类型--二进制文件
response.setContentType("application/octet-stream;charset=utf-8");
IOUtils.write(bytes,response.getOutputStream());
fis.close();
file.delete();
}