FileReader 在阅读 PDF 时丢失数据

Jul*_*enD 6 javascript pdf filereader

我只能以 JSON 格式将数据发送到服务器,我需要将 PDF 文件与 JSON 中的其他表单数据一起发送。我虽然我可以用 base64 从它制作一个字符串,就像我在 SO 上找到的这个解决方案一样:

let data = {foo: 1, bar: 2};
let reader = new FileReader();
reader.readAsDataURL(pdf);
reader.onload = () => {
  data.file = reader.result;
  $.ajax({type: 'POST', dataType: "json", data: JSON.stringify(data), ...});
}
Run Code Online (Sandbox Code Playgroud)

但碰巧reader.result不包含整个PDF(我是否将其保存到文件而不是发送,或从服务器取回)。在文本编辑器中,内容是相同的,但二进制编辑器会说丢失了一些字节。我的浏览器可以将其加载为 pdf 并显示标题,但页面是空白的。

我也尝试过reader.readAsBinaryString自己转换为 base64 btoa,但结果相同。

编辑:CodePen 示例:https ://codepen.io/jdelafon/pen/eRWLdz ? editors = 1011

编辑:为了验证,我这样做了:

let reader = new FileReader();
reader.readAsBinaryString(pdf);
reader.onload = () => {
    let blob = reader.result;
    let file = new Blob([blob], {type: 'application/pdf'});
    let fileURL = window.URL.createObjectURL(file);
    // make it display in <embed>
};
Run Code Online (Sandbox Code Playgroud)

pdf 的正文是空的。如果我替换file为 original pdf,它会完全显示。所以 FileReader 在这个过程中丢失了数据。

它知道标题和页数,但每个页面的正文都是空的

有没有更好的办法?这是编码问题FileReader吗?

我也想像这样使用 FormData :

let data = {foo: 1, bar: 2};
let fd = new FormData();
fd.append('file', pdf);
data.file = btoa(fd);
$.ajax({type: 'POST', dataType: "json", data: JSON.stringify(data), ...});
Run Code Online (Sandbox Code Playgroud)

但是现在当我从服务器取回数据时,JS 不知道它代表一个 FormData 对象,所以我不知道如何取回文件以在浏览器中显示。是否可以?

Jul*_*enD 1

Watilin 的答案没有添加,所以这里是从 Codepen 复制的工作片段:

function onUpload(input) {  
  let originalFile = input.files[0];
  let reader = new FileReader();
  reader.readAsDataURL(originalFile);
  reader.onload = () => {
    let json = JSON.stringify({ dataURL: reader.result });

    // View the file
    let fileURL = JSON.parse(json).dataURL;
    $("#display-pdf").empty();
    $("#display-pdf").append(`<object data="${fileURL}"
      type="application/pdf" width="400px" height="200px">
    </object>`);

    // View the original file
    let originalFileURL = URL.createObjectURL(originalFile);
    $("#display-pdf").append(`<object data="${originalFileURL}"
      type="application/pdf" width="400px" height="200px">
    </object>`)
    .onload(() => {
      URL.revokeObjectURL(originalFileURL);
    });
  };
}

Run Code Online (Sandbox Code Playgroud)

HTML:

<input id="file-input" type="file" onchange="onUpload(this)" />
<div id="display-pdf"></div>
Run Code Online (Sandbox Code Playgroud)