Vue所有图片预加载加上Token请求头信息、图片请求加载鉴权
环境
Vue2、“axios”: “0.18.1”、webpack:“4.46.0”、ant-design-vue: “1.7.8”
描述
项目对安全要求比较高,所有后台返回的图片加载时都要加上token。比如资源图片,拍照打卡的图片,都需要鉴权。如果不带上token参数,图片请求返回都是401,无法正常显示图片。
博客这里仅讨论前端实现。
使用
为了方面理解,先讲怎么使用,再讲具体的代码实现
组件使用
先看看组件方式怎么使用,项目用了 v-viewer 图片预览插件,使用方式:把原先的img标签换成BCTokenImage组件
<viewer ref="viewer">
<BCTokenImage style="width: 50px;height:40px;" v-for="item in result.images" :src="item.full_url" :key="item.id" />
</viewer>
非组件使用
网上有些方案是指令式的,也有些是querySeletor全局改,大家可以查一查
<img :src="fullUrl" v-token />
从代码实现上来说,逻辑大差不差的。因为需求紧急,img标签全局替换成组件是最快的方式(当然有些base64格式、静态图片会有问题,可以看我另一篇文章:Vue图片父子组件传入路径报错Error: Cannot find module ‘@/assets/map/red.png‘、动态加载require图片失败的问题)
实现
第一步,在 src/components 文件新增一个组件:BCTokenImage
位置:src\components\BCTokenImage\index.vue
<template>
<img :src="imageUrl" :alt="alt" @click="$emit('click')" />
</template>
<script>
import { axios } from '@/utils/http' // 封装过的axios,请求会自带token
import signMd5Utils from '@/utils/encryption/signMd5Utils'
export default {
name: "BCTokenImage",
props: {
src: String,
alt: String
},
data() {
return {
imageUrl: "", // 可以默认给一个占位图片
};
},
watch: {
src: {
handler(value) {
this.loadImage(value);
},
immediate: true,
}
},
methods: {
loadImage(url) {
const sign = signMd5Utils.getSign(url);
const headers = {
// "X-Access-Token": xxxxx, // 封装后axios对象自带了token头
"X-Sign": sign, // 签名(看具体需要)
"X-TIMESTAMP": signMd5Utils.getDateTimeToString(), // 时间戳(看具体需要)
};
axios({
method: 'get',
responseType: 'blob', // 重要:设置响应类型为blob
url,
headers, // 重要:将签名和时间戳,添加在请求接口 Header
}).then(response => {
// 创建一个URL,浏览器可以使用它来加载图片
this.imageUrl = URL.createObjectURL(new Blob([response]));
}).catch(error => {
console.error(`BCTokenImage error: ${url}加载失败!`, error);
});
}
}
};
</script>
主要是看 loadImage 方法的逻辑,因为项目封装了axios对象,默认给请求加上token,所以这个方法的请求头没带上X-Access-Token。
第二步,在 main.js 全局注册组件
import Vue from 'vue'
import BCTokenImage from '@/components/BCTokenImage'
Vue.component('BCTokenImage', BCTokenImage) // 全局注册
当然局部引入也是可以的,具体使用方式请看前面的 《使用》
效果
最终效果要看控制台的图片请求头,header成功带上了三个参数,图片请求返回不再是401
感兴趣也可以看看请求的响应内容,返回的是二进制数据
好啦,图片请求鉴权到此结束,谢谢观看,有问题评论区讨论