Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Mozilla PDF-如何在react应用程序中从url查看PDF?_Javascript_Reactjs_Pdfjs_Pdfjs Dist - Fatal编程技术网

Javascript Mozilla PDF-如何在react应用程序中从url查看PDF?

Javascript Mozilla PDF-如何在react应用程序中从url查看PDF?,javascript,reactjs,pdfjs,pdfjs-dist,Javascript,Reactjs,Pdfjs,Pdfjs Dist,我已经学习了一个关于如何使用React实现Mozilla的PDF查看器的快速教程。我做了一个密码箱。我想知道这是否可以通过导入pdfjs的节点模块来实现。 因此,与其将软件包下载到公用文件夹中以将其与导入一起使用,不如: export default class PDFJs { init = (source, element) => { const iframe = document.createElement("iframe"); iframe.

我已经学习了一个关于如何使用React实现Mozilla的PDF查看器的快速教程。我做了一个密码箱。我想知道这是否可以通过导入pdfjs的节点模块来实现。 因此,与其将软件包下载到公用文件夹中以将其与导入一起使用,不如:

export default class PDFJs {
  init = (source, element) => {
    const iframe = document.createElement("iframe");

    iframe.src = `/pdfjs-2.5.207-dist/web/viewer.html?file=${source}`;
    iframe.width = "100%";
    iframe.height = "100%";

    element.appendChild(iframe);
  };
}
此外,当PDF的源是URL时,这种设置不起作用。如果我这样做,我会得到一个错误:

PDF.js v2.5.207(内部版本:0974d6052)消息:文件来源不匹配 观众的

我已经在pdfjs-2.5.207-dist/web/viewer.js中注释掉了代码中检查文件来源的部分:

  //if (origin !== viewerOrigin && protocol !== "blob:") {
  //  throw new Error("file origin does not match viewer's");
  //} 
但是,后来我犯了一个错误:

PDF.js v2.5.207(内部版本:0974d6052) 消息:获取失败

我怎样才能解决这个问题?
是否可以将此包像模块一样导入react组件,以及如何将其用于带有URL的外部资源中的PDF?

我对您的示例进行了更改,使其接受URL

我的代码如下

import pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";
const pdfjsLib = import("pdfjs-dist/build/pdf");

export default class PDFJs {
  init = (source, element) => {
    pdfjsLib.then((pdfjs) => {
      pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;
      var loadingTask = pdfjs.getDocument(`${source}`);
      loadingTask.promise.then((pdf) => {
        pdf.getPage(1).then((page) => {
          var scale = 1.5;
          var viewport = page.getViewport({ scale: scale });
          var canvas = document.createElement("canvas");
          var context = canvas.getContext("2d");
          canvas.height = viewport.height;
          canvas.width = viewport.width;
          element.appendChild(canvas);
          var renderContext = {
            canvasContext: context,
            viewport: viewport
          };
          page.render(renderContext);
        });
      });
    });
  };
}

您可以看到结果

推荐人策略:与外部来源交叉/使用时严格来源 pdf应位于同一主机上(包括同一协议)。将pdf托管在与应用程序/网站相同的url上,应该可以解决此问题

允许在其他页面中加载pdf可能会导致各种安全风险

如果您想在自己的主页上显示外部pdf的最新版本,基本上有两种选择

在服务器上托管PDF

cp ./node_modules/pdfjs-dist/build/pdf.worker.js public/scripts
pdfjsLib.GlobalWorkerOptions.workerSrc = `${process.env.PUBLIC_URL}/scripts/pdf.worker.js`
运行服务器脚本(cron),下载pdf并将其托管在您自己的服务器上

允许交叉原点

npm install pdfjs-dist
如果您有权访问托管pdf的服务器,则可以发送标题以允许跨源

Access-Control-Allow-Origin: *
如何将pdfjs与纱线/npm结合使用 这方面的文档非常糟糕,但是他们有一个存储库
pdfjs dist
和一些相关文档

安装

npm install pdfjs-dist
用法(从)

服务人员

cp ./node_modules/pdfjs-dist/build/pdf.worker.js public/scripts
pdfjsLib.GlobalWorkerOptions.workerSrc = `${process.env.PUBLIC_URL}/scripts/pdf.worker.js`
您确实需要服务工作者-没有它,pdfjs无法工作,因此PDF也无法工作

如果您使用CRA,但不想使用CDN,则可以执行以下步骤:

1)将工作人员复制到公用文件夹

cp ./node_modules/pdfjs-dist/build/pdf.worker.js public/scripts
pdfjsLib.GlobalWorkerOptions.workerSrc = `${process.env.PUBLIC_URL}/scripts/pdf.worker.js`
2)注册服务人员

cp ./node_modules/pdfjs-dist/build/pdf.worker.js public/scripts
pdfjsLib.GlobalWorkerOptions.workerSrc = `${process.env.PUBLIC_URL}/scripts/pdf.worker.js`
下面是一个使用Mozilla查看器和您的pdf的示例

注意事项:

  • 您的pdf必须通过HTTPS提供,否则会出现以下错误:
  • 混合内容:页面位于'https://codesandbox.io/”他说 HTTPS,但请求了不安全的资源 'http://www.africau.edu/images/default/sample.pdf'. 这项请求已被批准 被封锁;内容必须通过HTTPS提供

  • 托管pdf的服务器应允许您的应用程序域使用
    访问控制允许源站
    ,或位于同一源站,否则您会遇到以下错误:
  • 取 'https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf' 源于https://lchyv.csb.app'已被CORS策略阻止: 请求的服务器上不存在“Access Control Allow Origin”标头 资源。如果不透明的响应满足您的需要,请设置请求的 模式设置为“无cors”,以获取禁用cors的资源

  • 为了演示,我使用了
    https://cors-anywhere.herokuapp.com/
    ,为您设置
    访问控制允许原点:
    ,但不应在生产中使用
    总之,由于浏览器的限制,您的pdf无法加载。直接在应用程序中导入
    pdfjs
    ,从头开始构建查看器(这是一项艰巨的工作)并不能解决这些问题。

    注意:正如其他人已经说过的那样,仅使用react(或任何客户端库),如果不解决CORS问题,就不可能获取外部资源(在您的情况下为PDF)。您将需要某种服务器端技术来解决它。(除非您拥有/有权访问外部资源服务器)
    查看您提供的沙盒代码,您似乎已经在使用node js,但该解决方案适用于所有应用程序

    基本上,您会请求服务器为您获取文件,然后将文件作为响应负载返回。 例如,节点服务器在
    fetchPdf
    上侦听请求,并将文件本身作为响应返回

    app.post('/fetchPdf',异步中间件(异步(req,res,next)=>{
    const pdfPath=等待下载文件(req.body.url);
    if(pdfPath){
    res.type('application/pdf');
    res.sendFile(pdfPath);
    res.on('finish',function(){
    试一试{
    fs.unlinkSync(pdfPath);
    }捕获(e){
    控制台错误(e);
    log(`无法删除文件${pdfPath}`);
    }
    });
    }否则
    res.status(404).send('notfound');
    }));
    函数下载文件(url){
    返回新承诺((解决、拒绝)=>{
    const absoluteFilePath=path.join(uuu dirname,`public/${crypto.randomBytes(20).toString('hex')}.pdf`);
    const file=fs.createWriteStream(绝对文件路径);
    log(`Requested url${url}`);
    const request=http.get(url,函数(downloadResponse){
    downloadResponse.pipe(文件).on('finish',()=>{
    解析(绝对文件路径);
    });
    }).on('error',函数(err){
    fs.unlink(绝对文件路径);
    解析(空);
    });
    });
    }
    
    注意:出于教育和学习的目的,这是可行的,但是以这种方式将代码部署到生产环境中存在各种安全问题。

    首先,您的服务器应该能够向Internet上的任何站点发出请求
    其次,如果没有某种身份验证,您的站点将成为任何希望下载被CORS阻止的外部资源的人的热点 (类似于