【问题标题】:pdf.js and protected files not otherwise viewablepdf.js 和受保护的文件以其他方式无法查看
【发布时间】:2017-09-19 23:06:46
【问题描述】:

我正在使用 PDF.js 库在我的站点中显示 PDf 文件(使用 pdf_viewer.js 在屏幕上显示文档),但我显示的 PDF 文件是机密文件,我需要能够显示它们在网站内,但阻止未经授权的公共人员通过输入 URL 并看到它们直接显示在他们的浏览器中来查看相同的文件。

我尝试在我的 htaccess 文件中添加 Deny from all 行,但这也阻止了查看器显示文档,所以这似乎是不行的。显然,任何人都可以简单地查看检查器并查看查看器正在读取的 pdf 文件,因此看起来直接 URL 无论如何都不安全。

我确实读过关于 PDF.js 能够读取二进制数据的信息,但我不知道如何在自己的文件系统中读取 PDF 并准备它以供图书馆使用,即使这意味着它是加载以获取文件内容并即时准备它的速度要慢一些。

任何人都有一个解决方案,允许 PDFJS 在不泄露源 PDF URL 的情况下工作,或者以其他方式使用本地文件调用读取文件?

【问题讨论】:

  • 有什么代码可以提供吗?
  • 好吧,来自 pdf.js 代码: * @param {string|TypedAray|object} source 可以是一个指向 PDF 所在位置的 URL *,一个类型化数组 (Uint8Array) 已经填充了数据或 * 和带有以下可能字段的参数对象: * - url - PDF 的 URL。 * - 数据 - 带有 PDF 数据的类型化数组。 * - httpHeaders - 基本身份验证标头。 * - 密码 - 用于解密受密码保护的 PDF。清楚地传递一个 URL 会将该 URL 暴露给外界,但我不清楚如何将 PDF 文件转换为指定的类型化数组。
  • 很明显,如果我可以私下阅读 PDF 文件,然后将其转换为 PDFJS 库可用的内容,我可以使用显示在 Inspector 的“网络”选项卡中的所有 URL,打开和使用文件的掩码名称读取和转换并传回要显示的数据。
  • PDF 有密码保护 -- 使用它,例如为每个文档生成唯一密码并在客户端解密

标签: file pdf base64 pdfjs


【解决方案1】:

好的,经过一番测试,解决方法很简单:

使用 Ajax 调用函数获取 PDF 数据,该函数可以确定要查看的实际文件。 在那个 PHP 文件中...... 正常使用 fopen 和 fread 将文件读入内存。 使用 base64_encode 转换为 base64 将该字符串传递回调用 Javascript。

在原来的调用函数中,使用以下将字符串转换为 Uint 数组,然后将其传递给 PDFJS 库...

## The function that turns the base64 string into whatever a Uint8 array is...
function base64ToUint8Array(base64) {
  var raw = atob(base64);
  var uint8Array = new Uint8Array(raw.length);
  for (var i = 0; i < raw.length; i++) {
    uint8Array[i] = raw.charCodeAt(i);
  }
  return uint8Array;
}

## the guts that gets the file data, calls the above function to convert it, and then calls PDF.JS to display it
$.ajax({
type: "GET",
data: {file: <a file id or whatever distinguishes this PDF>},
url: 'getFilePDFdata.php',  (the PHP file that reads the data and returns it encoded)
success: function(base64Data){
      var pdfData = base64ToUint8Array(base64Data);
      ## Loading document.
      PDFJS.getDocument(pdfData).then(function (pdfDocument) {
       ## Document loaded, specifying document for the viewer and
       ## the (optional) linkService.
      pdfViewer.setDocument(pdfDocument);
      pdfLinkService.setDocument(pdfDocument, null);        
    });
   }
});

【讨论】:

  • base64 在 php 和浏览器端是巨大的内存消耗,每个字节额外使用 2.5 个字节(您可以注意到 base64ToUint8Array 函数将为 base64 分配 2.5*n,为 row 分配 2*n,为 uint8Array 分配 n一次字节——总共 5.5*n 只使用 fetch() 或 XHR+arraybuffer)
  • re:protection,在ajax处/之后设置断点并在控制台中输入window.open('data:;base64,'+base64Data)会将数据保存在下载文件夹中,不是吗?
猜你喜欢
  • 2014-12-24
  • 2011-03-11
  • 2020-05-02
  • 2014-11-07
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多