需求描述:
vite + ts + vue3
后端接口返回 pdf 文件流,前端实现预览 pdf 文件
实现思路:
- 后端返回 pdf 文件流,前端通过 iframe 预览
代码实现:
1.添加接口请求配置
export const getReportDoc = (params?: getReportDocParam): any => {
return API.GET(`${baseUrl}/getReportDoc`, params, {
responseType: "blob", // 配置响应类型 blob
});
};
2.封装 pdfVue.vue 组件
<script setup lang="ts">
withDefaults(
defineProps<{
showPdf?: boolean;
pdfUrl?: any;
}>(),
{
showPdf: () => false,
pdfUrl: () => "",
}
);
</script>
<template>
<div class="pdfView">
<iframe
v-if="showPdf"
ref="iframe"
id="ifream"
width="100%"
height="100%"
:src="pdfUrl"
/>
</div>
</template>
<style scoped lang="less">
.pdfView {
width: 100%;
height: 100%;
}
</style>
3.使用 pdfView 组件
<template>
<div class="pdfView">
<PdfView :showPdf="showPdf" :pdfUrl="pdfUrl" />
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
const showPdf = ref(false);
// 调用获取文件流接口
const handleGetPdf = async () => {
try {
const res = await getReportDoc({ reportDocId: state.reportDocId });
state.pdfUrl = window.URL.createObjectURL(res) + "#toolbar=1";
} catch (error) {
console.log(error);
}
};
</script>
4.登录失效时跳转登录页情况该接口的判断
- import.meta.env.XX : vite 获取环境变量的方式
// 登录失效时执行的方法
const unLoginTips = (response: any) => {
ElMessage.error({
message: "登录已失效,请重新登录",
onClose: () => {
Promise.reject(response);
if (import.meta.env.VITE_USER_NODE_ENV === "development") {
// 开发环境跳转登录页
location.href = "/login";
} else {
// 其他环境跳转登录页(我的前端项目是和其他前端项目及后端部署在一起的,所以不是根目录)
window.location.href = `${window.location.origin}/ris/static/ris/index.html#/login`;
}
},
});
};
// 接口响应拦截
API.interceptors.response.use(
(response: any) => {
if (response.status === "0") { // 正常返回数据
return response;
} else if (["010x022", "010x028"].includes(response.status)) { // 登录失效
localStorage.clear();
unLoginTips(response);
} else if (response instanceof Blob) { // 重点!!!!!!判断响应类型为 Blob 的情况
if (response.type !== "application/pdf") { // 重点!!!!!!登录失效时跳登录页
unLoginTips(response);
return;
}
return response; // 否则正常返回文件流数据
} else {
ElMessage({
message: response.message || "服务器繁忙,请稍后重试~",
type: "error",
});
Promise.reject(response);
}
},
(error) => {
const { status, data } = error.response;
ElMessage({
message: data?.msg || `服务器繁忙(${status}),请稍后重试~`,
type: "error",
});
return Promise.reject(new Error(data?.msg || "Error"));
}
);