a 元素的 HREF 中的 PDF 下载结果为空 PDF

PDF Download in HREF of a-element results in empty PDF

我使用元素作为文件的下载按钮,我必须按照 here, here and 的描述使用 AJAX 查询文件。我将文件数据作为 Data-URI 放入 a 元素中以创建下载按钮。不幸的是,我不能只指向文件,而是必须那样做。对于大多数下载格式 HTML,CSV 的工作方式如下:

var mimeType = "text/html"; // example. works also with others.
var BOM = '\ufeff';
var url = "data:"+ mimeType +";charset=UTF-8," + BOM + encodeURIComponent(response.data);
var linkElem = document.querySelector("#hiddenDownloadLink");
var link = angular.element(linkElem);
link.prop("href", url);
link.prop("download", 'myFile.' + extension);
linkElem.click();

好的。这样可行。但不适用于 PDF。

我在后端创建了一个 PDF(java,使用 openhtmltopdf,但我想没关系,因为 PDF 绝对正确):

httpOutputMessage.getHeaders().add(HttpHeaders.CONTENT_TYPE, "application/pdf");
httpOutputMessage.getHeaders().add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"myFile.pdf\"");
makePdf(httpOutputMessage.getBody());

如果我直接查询后端,或者即使我将输出记录到一个文件中,一切都很好。但是当我如上所述使用我的下载控制器时,我得到了一个页数正确但完全是空的 PDF! 我认为一定是编码问题。我尝试使用和不使用 BOM,也尝试使用或不使用 encodeURIComponent。

我也试过使用base64-decoding as。因为 window.atob(response.data) 因为换行等原因失败,我尝试了 this 转换。结果是损坏的 PDF。导致损坏的 PDF。我不确定这是否有意义。

我的 PDF 数据是这样开始的,所以无论如何都没有压缩或编码:

%PDF-1.4
%����
1 0 obj
<<
/Type /Catalog
/Version /1.7
/Pages 2 0 R
>>
endobj
3 0 obj
<<

我还尝试将字节流转换为 blob,并按照 here orhere 所述生成 link,但这会创建损坏的 PDF。

任何想法,为什么我得到空的 PDF 或这里可能出了什么问题,我怎样才能重新下载-link?

-- 编辑 1

我也得到了有效的,但是当我尝试时是空白的 PDF

var blob = new Blob([response.data], {type: 'application/pdf'});
var url = window.URL.createObjectURL(blob);
link.prop("href", url);

当我通过此函数传送 response.data 时,我得到了一个损坏的 PDF。

var utf8_to_b64 = function(str) {
  var unescape = window.unescape || window.decodeURI;
  str = encodeURIComponent(str);
  str = unescape(str);
  str = window.btoa(str);

  return str;
};

所以我可以完全重现你的情况。我通过来自后端的 AJAX 请求加载并输出了一个 4 页的 PDF 文件,并且您的代码示例得到了一个 4 页的空白 PDF。

这是我之后所做的(并下载了正确的 PDF):

我对后端的输出进行了 base64 编码。在我的例子中,我使用的是 PHP 所以它是这样的:

$pdf = file_get_contents('test.pdf');
header('Content-Type: application/pdf');
echo base64_encode($pdf);

然后在前端我只改变了这一行:

var url = "data:"+ mimeType +";charset=UTF-8," + BOM + encodeURIComponent(response.data);

对此:

var url = "data:"+ mimeType +";base64," + encodeURIComponent(response.data);

希望这对您有所帮助。