项目中的那些事---下载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年前就看过 ...
随机推荐
- Linux定时重启
1.安装crontabyum install cixie-cron yum install crontabs 2.编辑cron第一步,登陆账号第二步,输入crontab -e第三步,输入i ...
- 解决Mybatis的invalid bound statement (not found)异常
使用Maven构建SSM时, 需要在pom.xml中配置一些信息, 否则mapper.xml就无法被扫描到, 程序就会抛invalid bound statement (not found)异常 解决 ...
- nodejs vue 微信公众号开发(二)申请微信测试号
1.打开微信测试公众号开发平台http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login 扫码登陆
- 07.27NOIP模拟赛
戳这里下载过去三次NOIP模拟赛总成绩 (别嘲笑垫底的我...解压密码为信奥生所在的两个班的班号,文档密码为机房开机用户名+密码) 又一次垫底…… 我难受. 上来感觉T1不可做,T2和蔼可亲,T3一脸 ...
- VS2012 TFS 解决计算机改名无法连接TFS的问题
闲着没事改了下计算机名字,结果造成TFS无法连接. 报错讯息如下: ---------------------------Microsoft Visual Studio-------------- ...
- System.Web.Mvc.ValueProviderResult.cs
ylbtech-System.Web.Mvc.ValueProviderResult.cs 1.程序集 System.Web.Mvc, Version=5.2.3.0, Culture=neutral ...
- 并查集 (poj 1611 The Suspects)
原题链接:http://poj.org/problem?id=1611 简单记录下并查集的模板 #include <cstdio> #include <iostream> #i ...
- <每日一题>题目28:生成随机的测验试卷(单选题)
#项目:生成随机的测验试卷文件 import random #资料库 capitals = {'北京市':'京','上海市':'沪','天津市':'津','重庆市':'渝','河北省':'冀','山西 ...
- elasticsearch 中文API 更新(五)
更新API 你能够创建一个UpdateRequest,然后将其发送给client. UpdateRequest updateRequest = new UpdateRequest(); updateR ...
- ArcMap中给点shp添加字段后,shp文件破坏无法打开
这两天遇到一个奇怪的问题,在整理项目中的建筑物数据时发现,有几个图层进行字段添加后出现问题,shp文件被损坏了.这问题很隐蔽,给shp添加字段后不报错,进行赋值,报错如下: 但是无论是选择“是”还是“ ...