一、前言
最近要做一下json
文件下载的功能,就是点击一个按钮,然后执行下载操作。本来这种下载应该是很简单的,不过博主在实际操作的时候,还是遇到了不少问题,记录一下。
二、ajax不能下载文件
1、为什么不能下载
如标题所示,本来是通过ajax
请求链接下载文件的,文件返回的数据也能在控制台看到,但就是不能调起浏览器的下载功能。header
怎么设置都没用,最后百度才知道,ajax
的请求是不能下载文件的,这涉及到安全的问题。
ajax
只能获取到string
类型的内容,不能处理二进制信息。在response
里面可以看到返回的文件字符串,ajax
方式请求的数据只能存放在javascipt
内存空间,可以通过javascript
访问,但是无法保存到硬盘,因为javascript
不能直接和硬盘交互,否则将是一个安全问题。但是无法操作磁盘进行保存等操作。
参考:https://blog.youkuaiyun.com/w405722907/article/details/77366843
2、其他方案
既然ajax
不行,那就选择其他方案,博主这里提供两个方案:
(1)模拟表单:
function downloadFileByForm(data) {
//此处data是需要传递的数据
var url = "../Project/OutboundOrderExcel"; //提交数据和下载地址
var form = $("<form></form>").attr("action", url).attr("method", "post");
//将数据赋值给Input进行form表单提交数据
form.append($("<input></input>").attr("type", "hidden").attr("name", "queryJson").attr("value", data));
form.appendTo('body').submit().remove(); //模拟提交
}
(2)使用a链接
第一种方式:一种是直接写到a标签内,优点是很方便,缺点就是错误提示,比如文件不存在等,错误提示会打开新的页面(请求的链接)显示提示,显然体验是不大好的。
第二种方式:点击按钮,然后通过给a标签的href赋值,然后调用a标签的点击方法,代码如下:
//ajax成功之后,给a标签的href赋值,然后调用a标签的点击事件
if(response.code == 200){ //给a标签赋值
console.log(1);
$("#click_upload").attr("href","?r=privacy/misc/recruit-json&projectId="+projectId);
var evt = document.createEvent("MouseEvents");
evt.initEvent("click", true, true);
document.getElementById("click_upload").dispatchEvent(evt);
}else{
alert(response.message);
}
这种方式的,提示会在本页面提示,看起来好一点。
关于在一个点击事件里面调用另一个点击事件参考:
https://blog.youkuaiyun.com/xmtblog/article/details/38319545
三、php解析json文件,返回json数据流
$filename是文件的路径
//声明浏览器输出的是字节流
$file = fopen($filename, "rb");
$title="job.json";
header('Content-Type: application/json');
Header( "Accept-Ranges: bytes ");
Header( "Content-Disposition: attachment;filename= $title");
while (!feof($file)) {
echo fread($file, 8192);
ob_flush();
flush();
}
fclose($file);
输出的部分比较简单,设置好header头就好,读取文件内容,然后返回即可
end