pdf.js + vite + vue3 打包到线上报错:Expected a JavaScript module script but the server responded with a MIME type of “application/octet-stream”.
问题描述:
本地预览OK。但build到线上后发现浏览器控制台报错:
Expected a JavaScript module script but the server responded with a MIME type of "application/octet-stream". Strict MIME type checking is enforced for module scripts per HTML spec.
原因分析:
ps:vite打包后放在public中的文件是直接使用,且pdf.js为4.0+的版本
vue3 调用pdf代码:
<template>
<div>
<el-icon>
<Memo @click="openHelp" />
</el-icon>
</div>
</template>
<script setup name="HelpDoc">
const pdfUrl = ref('');
//接口地址
const fileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/common/userOperation")
// pdf路径地址前缀
const prefixUrl = ref('/pdf/web/viewer.html?file=')
function openHelp(){
// 本地静态文件方式
// pdfUrl.value = prefixUrl.value + encodeURIComponent("/public/pdf/xx.pdf")
// 接口调用方式
pdfUrl.value = prefixUrl.value + fileUrl.value
// 打开空白页
window.open(pdfUrl.value, '_blank')
}
</script>
springboot 后端接口
/**
* 下载用户说明手册PDF
*/
@GetMapping("/userOperation")
public void downloadUserOperation(HttpServletResponse response, HttpServletRequest request) {
try {
String filePath = SystemConfig.getProfile() + File.separator + PDF_USER_OPERATION_MANUAL;
// 设置正确的Content-Type
response.setContentType(MediaType.APPLICATION_PDF_VALUE);
FileUtils.setAttachmentResponseHeader(response, PDF_USER_OPERATION_MANUAL);
FileUtils.writeBytes(filePath, response.getOutputStream());
// 设置正确的HTTP状态码
response.setStatus(HttpServletResponse.SC_OK);
} catch (Exception e) {
log.error("下载文件失败", e);
// 如果有错误发生,设置错误状态码
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
结论
- nginx无法识别mjs,从而在http header中错误的使用 Content-Type:application/octet-stream 来传输mjs文件,导致浏览器端认为它不是一个合法的js脚本。
- 其中后端接口response的ContentType为 application/pdf,nginx也无法识别application/pdf
解决方案:
修改nginx 配置文件conf:
server {
# 添加 mime types 配置
include mime.types;
types {
application/javascript mjs js;
application/pdf pdf;
}
}