Javascript Mozilla PDF-如何在react应用程序中从url查看PDF?
我已经学习了一个关于如何使用React实现Mozilla的PDF查看器的快速教程。我做了一个密码箱。我想知道这是否可以通过导入pdfjs的节点模块来实现。 因此,与其将软件包下载到公用文件夹中以将其与导入一起使用,不如: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.
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的示例
注意事项:
访问控制允许源站
,或位于同一源站,否则您会遇到以下错误: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阻止的外部资源的人的热点 (类似于