项目中的那些事---下载pdf文件
最近做了一个下载pdf文档的需求,本以为使用HTML5中<a>标签的属性download就能简单搞定,不料IE竟然不支持这一简单粗暴的H5新特性,而是直接在网页中打开,
于是各种搜索之后得出以下结论:IE中下载文档时,要想直接下载而不是在浏览器中打开,就要给下载的请求添加一些header属性:
1、Content-Disposition: attachment; filename=filename
2、Content-Type: application/octet-stream;
现在以我做的项目为例,总结一下在IE中下载pdf等类型文档的方法:
1、服务器端语言:PHP
2、前端语言:Jquery
因为要设置header,所以只能走服务器
第一步:前端创建一个下载文件的按钮
<button class="btn btn-small btn-warning" id="df">下载pdf文档</button>
这里面的class是bootstrap中的样式,用过bootstrap的人应该都很熟悉,这里不再赘述
第二步:给这个按钮添加点击事件,当点击该按钮时发起一个下载文档的请求给服务器
$("#df").click(function(){
$.ajax({
url:"downloadFile",
type : 'POST',
dataType : 'json',
success : function (m) {
if (m.status == 1) {
location.href = "downloadFile"
} else {
showAlert(m.info);
}
}
});
});
这里使用ajax请求,downloadFile为请求的服务端方法,当服务器接收到该请求之后就会做出响应,即下一步
第三步:服务器接受并响应请求
public function downloadHelp(){
/*设置文档的路径*/
$fileDir = SERVER_PATH . 'static/help/'; if (IS_POST) {
if (!is_dir($fileDir)) {
mkdir($fileDir, 0777, true);
} $filePath = $fileDir . '下载文档.pdf'; if (!is_file($filePath)) {
$this->ajax_return(0,"文档不存在");
} else if (!is_readable($filePath)) {
$this->ajax_return(0,"文档不可读");
} else {
$this->ajax_return(1);
}
} else {
$ua = $_SERVER["HTTP_USER_AGENT"];
$fileName = '下载文档.pdf';
$encoded_filename = urlencode($fileName);
$encoded_filename = str_replace("+", "%20", $encoded_filename);
$url = $fileDir . $fileName;
$fileSize = filesize($url);
header("Cache-Control: private");
header("Content-Type: application/octet-stream;");
header("Accept-Ranges: bytes");
header("Accept-Length: " . $fileSize * 1024);
/*
* 根据浏览器设置下载文件名称为中文时的编码
*/
if (preg_match("/MSIE/", $ua) || strpos($ua,"rv:11.0")) {
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
} else if (preg_match("/Firefox/", $ua)) {
header('Content-Disposition: attachment; filename*="utf8\'\'' . $fileName . '"');
} else {
header('Content-Disposition: attachment; filename="' . $fileName . '"');
} readfile($url);
exit;
}
}
上面代码中的方法其实是完成了两次客户端请求,
1、第一次请求方式是POST(可见js代码中的ajax请求),所以这时会判断文件是否存在以及是否具有读取权限等
2、第二次请求方式是GET,所以这时会根据第一次请求的结果决定下一步
(1)当staus="0",,提示"文档不存在" or "文档不可读"
(2)当status="1",设置header,并输出文件
其中值得注意的是,当下载的文件名为中文,且字符编码是UTF-8时,要根据浏览器类型进行设置,否则会出现文件名乱码的情况,上面的代码中已解决该问题,但是方法不止这一种,
所以再贴出解决下载文件名中文乱码的两种方法:
公共部分:
$ua = $_SERVER["HTTP_USER_AGENT"];
$fileName = '下载文档.pdf';
$encoded_filename = urlencode($fileName);
$encoded_filename = str_replace("+", "%20", $encoded_filename);
$url = $fileDir . $fileName; 第一种方法:
if (strpos($ua,"MSIE") || strpos($ua,"rv:11.0")) {
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
} else if (strpos($ua,"Firefox")) {
header('Content-Disposition: attachment; filename*="utf8\'\'' . $fileName . '"');
}else {
header('Content-Disposition: attachment; filename="' . $fileName . '"');
} 第二种方法:
if (preg_match("/MSIE/", $ua) || strpos($ua,"rv:11.0")) {
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
} else if (preg_match("/Firefox/", $ua)) {
header('Content-Disposition: attachment; filename*="utf8\'\'' . $fileName . '"');
} else {
header('Content-Disposition: attachment; filename="' . $fileName . '"');
}
其实这两种方法本质上没什么区别,只是我在测试的过程中发现,通过 $_SERVER["HTTP_USER_AGENT"]获取的浏览器信息中,如果浏览器是IE(我用的是IE11),
就没有“MSIE”这个字符串,导致即便是IE,strpos($ua,"MSIE")方法的结果还是false,所以无法解决IE中的乱码问题,于是就用strpos($ua,"MSIE")和preg_match("/MSIE/", $ua) 两种方法,
并在两种方法中都加上 strpos($ua,"rv:11.0"),这样才能判断出是IE浏览器,也就能顺利解决IE中文件名称中文乱码问题了。
以上就是本次下载pdf文档的需求中总结出的,本以为是个很简单的功能,没想到当它涉及到浏览器时竟有如此多的学问。
项目中的那些事---下载pdf文件的更多相关文章
- laravel项目中手机浏览器在线阅读pdf文件-->PDFJS插件
第一步:下载链接:http://mozilla.github.io/pdf.js/getting_started/#download 第二步:将下载的文件放在项目中. 第三步:在项目中想要预览的地方给 ...
- javaWeb项目中如何实现在线查看pdf文件
最近有需求要实现在网页直接查看pdf,word,excel文件.但是实际当中并没有很好的开源插件供我们使用,确实有一些付费的插件不错,也很好用,但是对于我来说都不适合. 现在只是单纯的找到了围魏救赵的 ...
- 阿里云OSS下载pdf文件,并在pdf文件上添加水印
代码: 兵马未动,粮草先行 作者: 传说中的汽水枪 如有错误,请留言指正,欢迎一起探讨. 转载请注明出处. 公司要求从阿里云OSS下载pdf文件并且需要添加水印. 因此这里总结一下. 首先添加了一个F ...
- 使用java的 htpUrlConnection post请求 下载pdf文件,然后输出到页面进行预览和下载
使用java的 htpUrlConnection post请求 下载pdf文件,然后输出到页面进行预览和下载 2018年06月07日 10:42:26 守望dfdfdf 阅读数:235 标签: jav ...
- Eclipse--Web项目中 .classpath、mymetadata、project文件的功用
Web项目中 .classpath..mymetadata..project文件的作用 创建Web Project时,会自动生成这个三个文件. 一..mymetadata文件 1.部署项目用的,把项目 ...
- 知网下载pdf文件的方法
title: 知网下载pdf文件的方法 toc: false date: 2018-11-02 17:54:43 categories: methods tags: 知网 平时我们使用的是国内版的知网 ...
- 在java项目中怎样利用Dom4j解析XML文件获取数据
在曾经的学习.net时常常会遇到利用配置文件来解决项目中一些须要常常变换的数据.比方数据库的连接字符串儿等.这个时候在读取配置文件的时候.我们一般会用到一个雷configuration,通过这个类来进 ...
- 从七牛服务下载PDF文件
/** * 从七牛下载PDF文件 * @param request * @param response * @param exhiId * @throws MalformedURLException ...
- .NET平台开源项目速览(16)C#写PDF文件类库PDF File Writer介绍
1年前,我在文章:这些.NET开源项目你知道吗?.NET平台开源文档与报表处理组件集合(三)中(第9个项目),给大家推荐了一个开源免费的PDF读写组件 PDFSharp,PDFSharp我2年前就看过 ...
随机推荐
- duilib教程之duilib入门简明教程5.自绘标题栏
如果大家有做过标题栏的自绘,肯定会感慨各种不容易,并且现有的一些资料虽然完美的实现了功能,但是代码比较乱,需要自行整理.如果用duilib,就是小case啦. duilib其实并没有区分标题栏和 ...
- ElasticSearch _bulk批量处理报错The bulk request must be terminated by a newline
在JSON数据最后回车换行,代码中可以
- springboot导入excel到mysql
@Controller @RequestMapping(path = "/excel") public class ImportController { @Autowired pr ...
- vue之vant组件下拉加载更多
vant地址:https://youzan.github.io/vant/#/zh-CN/intro 基础用法 List 组件通过loading和finished两个变量控制加载状态,当组件滚动到底部 ...
- CF1158F Density of subarrays
CF1158F Density of subarrays 首先可以发现,有值的p最大是n/c 对于密度为p,每个数至少出现c次,且其实是每出现c个数,就分成一段,这样贪心就得到了p %ywy n/c ...
- 19-10-29-Night-X
布谷. 欢迎大家来不耻下问. 这里是正解不会,暴力写跪,乱搞鸡肋的某虻 . 好想放假啊!!!! 话说猫厂现在产量低迷…… ZJ一下: T1,三维偏序,只码了$\Theta(N^2)$暴力 T2,暴力愉 ...
- hibernate查询timestamp条件
参考https://blog.csdn.net/zuozuoshenghen/article/details/50540661 Mysql中Timestamp字段的格式为yyyy-MM-dd HH-m ...
- 04-3-object类型
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vue-cli# 项目结构
引自:https://segmentfault.com/a/1190000007880723 http://blog.csdn.net/hongchh/article/details/55113751 ...
- svn插件的所有链接
http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240