如何用Javascript下载php格式的文件

xqnpmsa8  于 2023-03-16  发布在  PHP
关注(0)|答案(1)|浏览(150)

我有这段代码,它从PHP接收一个编码的base64文件,我需要用JavaScript下载到用户系统,但是当程序下载它时,文件没有任何信息,例如PDF文件是空的。
这是我的代码:

var name = json_obj['data']['nombre'];
var data = atob(json_obj['data']['archivo']);

var file = new Blob([data], {type: 'application/pdf'});

link = URL.createObjectURL(file);

var a = $("<a />");
a.attr("download", name);
a.attr("href", link);
$("body").append(a);
a[0].click();
$("body").remove(a);

PS:PHP运行良好,问题出在JS上

ljsrvy3e

ljsrvy3e1#

问题在于Blob对象如何序列化构造函数的第一个参数中提供的字符串,该参数是要包含在blob中的项的数组。字符串项被视为Unicode文本,并使用utf8编码在Blob输出中序列化。对于这个问题,它特别意味着提供给构造函数的base64字符串在blob输出中呈现为8位ASCII字符的字符串。而PHP应用程序查找的是解码后的二进制内容,而不是用于对其进行编码的base64字符。
提供从服务器上的PHP接收的base64字符串派生的下载链接的潜在解决方案包括:
1.在下载链接中使用data URL,而不创建Blob。
优点:简单,缺点:从历史上看,各种浏览器都对size of data URLs施加了限制。
1.从base64数据字符串创建一个blob并使用Object URL下载它;
另一种选择是在服务器上提供PHP端点来发送文件以响应来自前端的获取请求,这需要对应用程序架构进行更改。
下面的html页面演示了从base64字符串创建下载链接的两种方法,出于安全原因(可能是因为它以编程方式下载文件),它不能作为代码片段使用。
生成测试数据需要打开本地pdf文件才能使用其数据,但测试本身不会使用file对象读取。代码语法一直保持极其简单,但如果不需要支持过时的浏览器,则可以进行现代化。未尝试使用jQuery。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>PDF download</title>
</head>
<body>
<label>
  Open a pdf file for use as test data:
  <input type="file" id="fileBrowse" accept="application/pdf" onchange="testData.call( this,event)">
</label>
<hr>
<blockquote>
  <button type="button" disabled onclick="testDataURL()"> Download pdf as data URL</button>
<p>
  <button type="button" disabled onclick="testObjectURL()"> Download pdf from ObjectURL</button>
</blockquote>

<script>"use strict";
var json_data = null;
function testData(event) {
  var file = this.files[0];
  var fReader = new FileReader();
  fReader.onload = function(){
    var base64 = btoa( this.result);
    json_data = {
      data: { name: file.name, arquivo: base64 }
    };
    document.querySelectorAll("button").forEach( button => button.disabled=false);
  };
  fReader.onerror = function(err){ console.log(err);};
  fReader.readAsBinaryString(file);
}

// check validity of base64 string by using it in a data URL

function testDataURL() {
   var href = "data:application/pdf;base64," + json_data.data.arquivo;
   downloadLink(json_data.data.name, href, false);
}

// check code to download as ObjectUURL

function testObjectURL() {
   var base64 = json_data.data.arquivo;
   var bString = atob(base64); // binary string;
   var length = bString.length;
   var bytes = new Uint8Array(length);
   for( var i = 0; i < length; ++i) {
     bytes[i] = bString.charCodeAt(i);
   }
   var oURL = URL.createObjectURL( new Blob([bytes], {type: "application/pdf"}));
   downloadLink(json_data.data.name, oURL, true)
}

// download link common to both tests

function downloadLink( name, url, revoke) {
  var a = document.createElement('a');
  a.href = url;
  a.download = name;
  document.body.append(a);
  a.click();
  a.remove()
  if(revoke) {
    URL.revokeObjectURL(url);
  }
}
</script></body>
</html>

相关问题