pdf-FormatError Bad FCHECK in flate stream

在开发PDF页面预览的时候遇到一个奇怪的问题,预览某些发票的pdf的时候会遇到部分元素丢失的情况,网上找了一圈发现主要是由两个原因导致的,

字体丢失

使用pdf.js 预览的时候可以查看网络请求发现部分资源404,这会导致pdf字体渲染失败,元素丢失,主要是签章等数据
react-pdf的使用demo见此链接https://github.com/wojtekmaj/react-pdf/blob/main/packages/react-pdf/README.md
相关示例代码如下

import { useState } from 'react';
import { Document, Page } from 'react-pdf';
const options = {
  cMapUrl: `https://unpkg.com/pdfjs-dist@${pdfjs.version}/cmaps/`,
  standardFontDataUrl: `https://unpkg.com/pdfjs-dist@${pdfjs.version}/standard_fonts`,
};
function MyApp() {
  const [numPages, setNumPages] = useState<number>();
  const [pageNumber, setPageNumber] = useState<number>(1);

  function onDocumentLoadSuccess({ numPages }: { numPages: number }): void {
    setNumPages(numPages);
  }

  return (
    <div>
      <Document file="somefile.pdf" onLoadSuccess={onDocumentLoadSuccess} options={options}>
        <Page pageNumber={pageNumber} />
      </Document>
      <p>
        Page {pageNumber} of {numPages}
      </p>
    </div>
  );
}

*** 关注这个options相关配置 ***
当某些pdf文件没有把相关font信息打包进pdf的时候pdf.js会去这些资源地址下载,当然你也可以指定自己的cdn资源地址,这些资源的git地址在
https://github.com/mozilla/pdf.js/tree/master/external 这个目录下的bcmapsstandard_fonts

Invalid stream: “FormatError: Bad FCHECK in flate stream: 120, 253”

解析异常的报错,这个报错比较隐晦,在chrome下是warning,在Firefox下是error,但是不影响pdf的页面展示,只是会缺失元素。

这个bug的表象比较诡异:

    1. 当你把页面返回response复制下来保存成pdf文件的时候会发现确实会缺失元素。
    1. 当你用postman 去模拟接口访问的时候会发现postman里的返回页面是正常的。

就是同样的请求在postman里是正常的,在浏览器里是异常的,那么就几种种情况:要么可能出现了资源跨域,要么是接口请求的参数异常,或者兼容性问题。

通过一通搜索已经对比终于找到了相关的文档

responseType如果不修改,axios中默认的是json

我们需要指定返回的请求体类型


this.$request({
    methods: 'GET',
    url: `/api/preview?id=${id}`,
    responseType: 'blob'
})
.then(res => {
    console.log(res)
    var blob = new Blob([res.data], {
        type: 'application/pdf;chartset=UTF-8'
    })
    const fileURL = URL.createObjectURL(blob)
    window.open(`${path}pdf/web/viewer.html?file=${fileURL}`)
   //  URL.revokeObjectURL(fileURL) //释放URL对象 注意这句
});

提前释放Blob文件,导致下载和刷新失效

见上方代码的 URL.revokeObjectURL
这句代码本来是为了释放Blob的内存占用,但是如果你新开页面立即释放的化,会导致pdf下载失败,以及刷新页面文件找不到了。
至此,这个pdf展示相关的的问题算是解决了。

本文作者:番茄炒蛋
本文地址: https://www.noway.pub/2023/10/12/pdf_error-FormatError_Bad_FCHECK/
版权声明:转载请注明出处!