为什么不能直接使用 <embed> 标签预览流式 PDF 数据?
<embed>标签的src属性<embed>标签的src属性通常需要一个有效的 URL,指向一个外部资源(如文件路径、网络地址等)- 流式数据(如
ReadableStream或Blob)不能直接作为src属性的值
- 浏览器的处理方式
- 浏览器在处理
<embed>标签时,会根据src属性指定的 URL 发起网络请求,获取外部资源并嵌入到页面中 - 流式数据无法直接作为 URL 使用,因此浏览器无法正确处理
- 浏览器在处理
预览 pdf 的流式数据的解决办法
把可读流转成 Blob,再将 Blob 转成一个可临时访问的 url,代码示例如下:
<script>
export default {
methods: {
/**
* 将流转换为 Blob
* @param stream
* @returns Blob
*/
async streamToBlob(stream) {
const reader = stream.getReader()
const chunks = []
let done = false
while (!done) {
const { done: isDone, value } = await reader.read()
done = isDone
if (!done) {
chunks.push(value)
} else {
// 流读取完成的逻辑
}
}
return new Blob(chunks, { type: 'application/pdf' })
},
/**
* 预览 PDF
* @param url
*/
async previewPDF(url) {
try {
const response = await fetch(url)
if (!response.ok) {
throw new Error('加载 pdf 失败')
}
const blob = await this.streamToBlob(response.body)
const blobUrl = URL.createObjectURL(blob)
this.blobUrl[this.currentIndex] = blobUrl
} catch (e) {
this.$modal.msgError('加载 pdf 失败')
}
},
}
}
</script>