Javascript 使用pdf.js呈现pdf,但它不起作用,并且我没有收到任何错误消息来帮助我调试问题

Javascript 使用pdf.js呈现pdf,但它不起作用,并且我没有收到任何错误消息来帮助我调试问题,javascript,pdf,pdfjs,pdfjs-dist,Javascript,Pdf,Pdfjs,Pdfjs Dist,我正在尝试构建一个Flask应用程序,在这里我上传pdf,并在提交到后端之前预览它们 我使用的脚本如下所示: const imageUploadValidation = (function () { "use strict"; pdfjsLib.GlobalWorkerOptions.workerSrc = "https://mozilla.github.io/pdf.js/build/pdf.js"; const onFilePi

我正在尝试构建一个Flask应用程序,在这里我上传pdf,并在提交到后端之前预览它们

我使用的脚本如下所示:

const imageUploadValidation = (function () {
  "use strict";

  pdfjsLib.GlobalWorkerOptions.workerSrc =
    "https://mozilla.github.io/pdf.js/build/pdf.js";

  const onFilePicked = function (event) {
    // Select file Nodelist containing 1 file
    const files = event.target.files;
    const filename = files[0].name;
    if (filename.lastIndexOf(".") <= 0) {
      return alert("Please add a valid file!");
    }

    const fileReader = new FileReader();

    fileReader.onload = function (e) {
      const pdfData = e.target.result;

      let loadingTask = pdfjsLib.getDocument({ data: pdfData })
      loadingTask.promise.then(function (pdf) {
          console.log("PDF loaded", pdf);

          pdf.getPage(1).then((page) => {
            console.log("page loaded", page);
            // var scale = 1.5;
            // var viewport = page.getViewport({ scale: scale });

            var iframe = document.getElementById("image-preview");
            iframe.src = page
            // var context = canvas.getContext("2d");
            // canvas.height = viewport.height;
            // canvas.width = viewport.width;

            // var renderContext = {
            //   canvasContext: context,
            //   viewport: viewport,
            // };

            // var renderTask = page.render(renderContext);
            // renderTask.promise.then(function () {
            //   console.log("Page rendered");
            // });
          });
        })
        .catch((error) => {
          console.log(error);
        });
    };
    const pdf = fileReader.readAsArrayBuffer(files[0]);
    console.log("read as Data URL", pdf);
  };

  const Constructor = function (selector) {
    const publicAPI = {};

    const changeHandler = (e) => {
      // console.log(e)
      onFilePicked(e);
    };

    publicAPI.init = function (selector) {
      // Check for errors.
      const fileInput = document.querySelector(selector);
      if (!selector || typeof selector !== "string") {
        throw new Error("Please provide a valid selector");
      }

      fileInput.addEventListener("change", changeHandler);
    };

    publicAPI.init(selector);
    return publicAPI;
  };

  return Constructor;
})();

imageUploadValidation("form input[type=file]");
加载任务承诺似乎从未运行过。在那之前一切似乎都正常。我不熟悉这个Promise语法,所以我不能确定问题是否存在,或者我是如何传递pdf文件的

另外,注释掉的代码是我最初的设置方式,什么 s uncommented只是我用另一种方式进行测试。

检查数据类型 首先,您可能需要检查从文件读取器返回的内容,特别是pdfData的数据类型。如果查看文档,getDocument需要一个Unit8Array或二进制字符串

添加缺少的参数 下一个问题是调用getDocument时缺少必需的参数。以下是所需的最低参数:

var args = {
    url: 'https://example.com/the-pdf-to-load.pdf',
    cMapUrl: "./cmaps/",
    cMapPacked: true,
}
我从来没有用数据参数代替url,但只要提供正确的数据类型就可以了。请注意,cMapUrl应该是cmap文件夹的相对或绝对路径。PDFJS通常需要这些文件来实际解释PDF文件。以下是演示存储库GitHub页面中的所有文件:您需要将这些文件添加到您的项目中

我建议不要使用数据,而是将文件作为blob上传,然后只需将blob URL作为URL提供。我不熟悉如何做到这一点,我只知道它在现代浏览器中是可能的

您的查看器在哪里/您不需要iFrame或Canvas PDFJS只需要一个div就可以将PDF放入其中。它对一些CSS规则很挑剔,对于exmaple来说,它必须是绝对定位的,否则PDFJS会将页面生成为0px高度

我在你的代码中没有看到PDFViewer或PDFLinkService。看起来您正试图自己从头开始构建整个查看器。这是不小的努力。当loadingTask正常工作时,应对响应进行如下处理:

loadingTask.promise.then(
    // Success function.
    function( doc ) {
        // viewer is holding: new pdfjsViewer.PDFViewer()
        // linkService is: new pdfjsViewer.PDFLinkService()
        viewer.setDocument( doc );
        linkService.setDocument( doc );
    },
    // Error function.
    function( exception ) {
        // What type of error occurred?
        if ( exception.name == 'PasswordException' ) {
            // Password missing, prompt the user and try again.
            elem.appendChild( getPdfPasswordBox() );
        } else {
            // Some other error, stop trying to load this PDF.
            console.error( exception );
        }
        /**
         * Additional exceptions can be reversed engineered from here:
         * https://github.com/mozilla/pdf.js/blob/master/examples/mobile-viewer/viewer.js
         */
    }
);
请注意,PDFViewer为您完成了所有艰苦的工作。如果希望PDF中的链接正常工作,则需要PDFLinkService。你真的应该结帐了

这是一个很大的工作,但这些可以教你所有你需要知道的关于PDFJ

示例/示例代码 下面是我用PDFJS做的一个项目的一些示例代码。代码有点高级,但它应该可以帮助您对PDFJS如何在引擎盖下更好地工作进行反向工程

pdfObj=用于存储此PDF文件的所有信息和对象的对象。我在一个页面上加载了多个PDF,所以我需要这样才能使它们彼此分开

updatePageInfo=当用户更改PDF中的页面时,PDFJS的eventBus调用的My custome函数;当他们从一页滚动到另一页时,就会发生这种情况

pdfjsViewer.DownloadManager=我允许用户下载PDF,因此我需要使用它

pdfjsViewer.EventBus=处理PDF的加载、页面更改等事件。我不是100%确定,但我认为PDFViewer需要这样做

pdfjsViewer.PDFViewer=处理向用户实际显示PDF的操作。容器是页面上要呈现的元素,请记住它必须位于绝对位置

// Create a new PDF object for this PDF.
var pdfObj = {
    'container': elem.querySelector('.pdf-view-wrapper'),
    'document': null,
    'download': new pdfjsViewer.DownloadManager(),
    'eventBus': new pdfjsViewer.EventBus(),
    'history': null,
    'id': id,
    'linkService': null,
    'loaded': 0,
    'loader': null,
    'pageTotal': 0,
    'src': elem.dataset.pdf,
    'timeoutCount': 0,
    'viewer': null
};

// Update the eventBus to dispatch page change events to our own function.
pdfObj.eventBus.on( 'pagechanging', function pagechange(evt) { 
    updatePageInfo( evt );
} );

// Create and attach the PDFLinkService that handles links and navigation in the viewer.
var linkService = new pdfjsViewer.PDFLinkService( {
    'eventBus': pdfObj.eventBus,
    'externalLinkEnabled': true,
    'externalLinkRel': 'noopener noreferrer nofollow',
    'externalLinkTarget': 2 // Blank
} );
pdfObj.linkService = linkService;

// Create the actual PDFViewer that shows the PDF to the user.
var pdfViewer = new pdfjsViewer.PDFViewer(
    {
        'container': pdfObj.container,
        'enableScripting': false, // Block embeded scripts for security
        'enableWebGL': true,
        'eventBus': pdfObj.eventBus,
        'linkService': pdfObj.linkService,
        'renderInteractiveForms': true, // Allow form fields to be editable
        'textLayerMode': 2
    }
);
pdfObj.viewer = pdfViewer;
pdfObj.linkService.setViewer( pdfObj.viewer );

您好,非常感谢您提供的所有信息,这非常有用。我正要放弃完成这件事,只是看到了你的答案。我将尽快研究测试这一点。非常感谢你!!不客气!如果这有助于你解决问题,别忘了投票并标记为已回答。