前言
图片在前端开发中扮演了重要的角色,它们不仅仅是美观的元素,还可以传递信息和激发用户的兴趣。随着应用场景的增多,前端开发人员就需要在图片加载过程中携带验证的信息。如 token,用于身份验证、权限控制等方面。通过在图片的 URL 或请求头中携带 token 信息,从而实现图片信息的安全传输。
实现思路
- 创建一个名为
tokenImg
的组件,该组件用于显示图片并支持预览功能; - 在组件的模板中,使用
<img>
标签来显示图片,或使用element-ui
的<el-image>
标签进行图片预览; - 在组件的属性中,接收图片的
URL
地址 (imgUrl
)、图片类型 (imgType
)、图片的宽度 (width
) 和高度 (height
); - 在组件的数据中,定义预览图片列表 (
previewList
) 和预览图片路径 (previewpath
); - 实现两个方法
viewModel()
和preViewModel()
分别用于仅预览图片和带缩略图预览; - 在
viewModel()
方法中,通过调用下载文件的API (downloadFileApi)
并根据返回的文件内容创建URL
对象,将图片URL
赋值给<img>
标签的src
属性; - 在
preViewModel()
方法中,同样调用下载文件的API
,将返回的文件内容创建URL
对象,并将URL
添加到预览图片列表中; - 使用
watch
监听imgUrl
属性的变化,在变化时根据imgType
属性的值来调用对应的方法; - 在组件的
mounted()
钩子中,根据初始的imgType
属性值来调用对应的方法; - 在
main.js
文件中将tokenImg
组件注册为全局组件,以便在其他地方使用; - 在需要使用该组件的地方,使用
<TokenImg>
标签,并传递相应的属性(如图片URL
、图片类型、宽度和高度);
这样,你可以在前端中使用tokenImg
组件来显示带有Token
的图片,并支持预览功能。注意确保在组件使用时传递正确的图片URL
、类型、宽度和高度。
封装文件
<template>
<div>
<!-- 显示图片 -->
<img ref="img" :style="{width:width,height:height}" v-if="imgType == 'view'" />
<!-- 使用element-ui的el-image进行图片预览 -->
<el-image :style="{width:width,height:height}" ref="previewimg" v-if="imgType == 'preView'" :src="previewpath"
:preview-src-list="previewList"></el-image>
</div>
</template>
<script>
// 引入的接口文件
import { downloadFileApi } from "@/api/publicApi/enumeration";
export default {
name: "token-img",
props: {
// 图片的URL地址
imgUrl: {
type: String,
},
// 图片类型,可选为'view'(仅预览图片)或'preView'(可点击预览)
imgType: {
type: String,
default: "view",
},
// 图片的宽度
width: {
type: String,
},
// 图片的高度
height: {
type: String,
},
},
data() {
return {
// 预览图片列表
previewList: [],
// 预览图片路径
previewpath: "",
};
},
methods: {
//仅预览图片
viewModel() {
const img = this.$refs.img;
// 调用下载文件的API并根据返回的文件内容创建URL对象
downloadFileApi(this.imgUrl).then((res) => {
img.src = URL.createObjectURL(res);
img.onload = () => {
URL.revokeObjectURL(img.src);
};
});
},
//带缩略图预览
preViewModel() {
downloadFileApi(this.imgUrl).then((res) => {
// 调用下载文件的API并根据返回的文件内容创建URL对象
this.previewpath = URL.createObjectURL(res);
this.previewList.push(this.previewpath);
});
},
},
watch: {
// 监听imgUrl变化
imgUrl() {
if (this.imgType == "view") {
this.viewModel();
} else if (this.imgType == "preView") {
this.preViewModel();
}
},
},
mounted() {
if (this.imgType == "view") {
this.viewModel();
} else if (this.imgType == "preView") {
this.preViewModel();
}
},
};
</script>
引入的接口文件
responseType: "blob"
表示希望以二进制形式接收响应数据。这在处理文件下载或者需要以二进制形式处理响应数据的情况下非常有用。通过将 responseType
设置为 blob
,可以确保响应数据以 blob
对象的形式返回,然后可以进一步处理或者保存到本地。
export function downloadFileApi(imgUrl) {
return request({
url: "/api/file/examine-preview"+imgUrl,
method: "get",
responseType: "blob",
});
}
main.js
// 将其注册为全局组件
import TokenImg from "@/components/tokenImg";
Vue.component('TokenImg', TokenImg)
使用文件
<TokenImg :width="`50px`" :height="`50px`" :imgUrl="YourUrl" :imgType="`preView`"/>
实现效果
发起请求
渲染查看
拓展
一、微信小程序中实现该操作
封装文件 ----
.js
// 引入服务器请求封装的模块
const server = require('../../utils/server.js');
Component({
// 组件的内部数据
data: {
previewPath: "", // 预览图片路径
},
// 组件的对外属性,是属性名到属性设置的映射表
properties: {
imgUrl: { // 图片的URL地址
type: null,
observer: 'fetchData' // 监听imgUrl属性的变化,触发fetchData方法
},
imageWidth: { // 图片的宽度
type: String,
},
imageHeight: { // 图片的高度
type: String,
},
},
// 组件的方法,包括事件响应函数和任意的自定义方法
methods: {
// 发起请求获取图片数据
fetchData() {
let {
imgUrl
} = this.properties;
console.log(imgUrl);
if (typeof imgUrl === 'string') {
imgUrl = [imgUrl]; // 如果是字符串,转化为数组
}
// 处理多张图片
const imagePromises = imgUrl.map(url => {
return new Promise((resolve, reject) => {
const imageUrl = `http://192.168.0.6666/${url}`;
server.request({
url: imageUrl,
responseType: 'arraybuffer',
success: (res) => {
const base64 = wx.arrayBufferToBase64(res.data);
resolve(`data:image/png;base64,${base64}`);
},
fail: (error) => {
reject(error);
}
});
});
});
// 处理多张图片的 Promise
Promise.all(imagePromises)
.then(images => {
this.setData({
previewPath: images,
});
})
.catch(error => {
console.error(error);
});
},
// 点击预览图片
previewImageOn(e) {
const {
previewpath
} = e.target.dataset; // 解构获取预览图片URL
wx.previewImage({ // 调用微信预览图片的API
urls: [previewpath], // 需要预览的图片URL列表
});
},
}
});
封装文件 ----
.wxml
<view>
<block wx:for="{{previewPath}}" wx:for-index="index">
<image bindtap="previewImageOn" data-previewPath="{{item}}" src="{{item}}" mode="aspectFill"
style="width:{{imageWidth}};height:{{imageHeight}};" key="{{index}}" />
</block>
</view>
app.json
全局引入
"usingComponents": {
"token-img": "./components/tokenImg/tokenImg"
},
page.json
全局引入
{
"usingComponents": {
"token-img": "./components/tokenImg/tokenImg"
}
}
使用文件
<token-img imageWidth="100%" imageHeight="170rpx" imgUrl="{{details.tailImg}}"></token-img>
实现效果
二、下载文件携带 token
第一种方式:手写实现
//下载方法
getBgdzByGcsj(row) {
// 通过接口下载文件
downloadFileApiDown(row.bgdz).then((res) => {
// 将文件流转换为下载链接
const downloadUrl = URL.createObjectURL(res);
// 创建一个<a>标签
const link = document.createElement("a");
// 设置链接的URL为下载链接
link.href = downloadUrl;
// 设置下载的文件名为"报表管理.xls"
link.download = "报表管理.xls";
// 隐藏<a>标签
link.style.display = "none";
// 将<a>标签添加到页面的<body>中
document.body.appendChild(link);
// 触发<a>标签的点击事件,开始下载
link.click();
// 下载完成后删除<a>标签
document.body.removeChild(link);
});
}
第二种方式:使用插件(
file-saver
)
file-saver 是一个 JavaScript
库,用于在浏览器中保存文件。它提供了一种简单的方法来生成并保存文件,而不需要服务器参与。使用 file-saver
插件,你可以轻松地在前端生成和下载文件,无需发送文件请求到服务器和返回文件链接,大大简化了文件下载的过程。
file-saver
插件的主要功能是将通过 Blob
对象生成的文件下载链接保存到浏览器的下载路径中。它提供了以下几种方法:
1.
saveAs
方法
保存文件到本地。你可以使用 saveAs
方法来指定文件的内容和名称,然后将其保存到浏览器的下载路径。
2.
save
方法
保存文件到本地,与 saveAs
方法类似,但不会弹出文件保存对话框。
3.
createObjectURL
方法
创建 Blob
对象的 URL
。通过 createObjectURL
方法,你可以将 Blob
对象转换为可供下载的 URL
。
4.
revokeObjectURL
方法
释放之前创建的 URL
。一旦文件下载完成,你可以使用 revokeObjectURL
方法来释放已经创建的 URL
,以释放浏览器资源。
-
安装
npm install file-saver
-
引入
import { saveAs } from 'file-saver';
-
使用
// res 返回地址 saveAs(res, '报表管理.xls');