最近做了一个下载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文件的更多相关文章

  1. laravel项目中手机浏览器在线阅读pdf文件-->PDFJS插件

    第一步:下载链接:http://mozilla.github.io/pdf.js/getting_started/#download 第二步:将下载的文件放在项目中. 第三步:在项目中想要预览的地方给 ...

  2. javaWeb项目中如何实现在线查看pdf文件

    最近有需求要实现在网页直接查看pdf,word,excel文件.但是实际当中并没有很好的开源插件供我们使用,确实有一些付费的插件不错,也很好用,但是对于我来说都不适合. 现在只是单纯的找到了围魏救赵的 ...

  3. 阿里云OSS下载pdf文件,并在pdf文件上添加水印

    代码: 兵马未动,粮草先行 作者: 传说中的汽水枪 如有错误,请留言指正,欢迎一起探讨. 转载请注明出处. 公司要求从阿里云OSS下载pdf文件并且需要添加水印. 因此这里总结一下. 首先添加了一个F ...

  4. 使用java的 htpUrlConnection post请求 下载pdf文件,然后输出到页面进行预览和下载

    使用java的 htpUrlConnection post请求 下载pdf文件,然后输出到页面进行预览和下载 2018年06月07日 10:42:26 守望dfdfdf 阅读数:235 标签: jav ...

  5. Eclipse--Web项目中 .classpath、mymetadata、project文件的功用

    Web项目中 .classpath..mymetadata..project文件的作用 创建Web Project时,会自动生成这个三个文件. 一..mymetadata文件 1.部署项目用的,把项目 ...

  6. 知网下载pdf文件的方法

    title: 知网下载pdf文件的方法 toc: false date: 2018-11-02 17:54:43 categories: methods tags: 知网 平时我们使用的是国内版的知网 ...

  7. 在java项目中怎样利用Dom4j解析XML文件获取数据

    在曾经的学习.net时常常会遇到利用配置文件来解决项目中一些须要常常变换的数据.比方数据库的连接字符串儿等.这个时候在读取配置文件的时候.我们一般会用到一个雷configuration,通过这个类来进 ...

  8. 从七牛服务下载PDF文件

    /** * 从七牛下载PDF文件 * @param request * @param response * @param exhiId * @throws MalformedURLException ...

  9. .NET平台开源项目速览(16)C#写PDF文件类库PDF File Writer介绍

    1年前,我在文章:这些.NET开源项目你知道吗?.NET平台开源文档与报表处理组件集合(三)中(第9个项目),给大家推荐了一个开源免费的PDF读写组件 PDFSharp,PDFSharp我2年前就看过 ...

随机推荐

  1. selenium借助AutoIt识别上传(下载)详解【转】

    AutoIt目前最新是v3版本,这是一个使用类似BASIC脚本语言的免费软件,它设计用于Windows GUI(图形用户界面)中进行自动化操作.它利用模拟键盘按键,鼠标移动和窗口/控件的组合来实现自动 ...

  2. 介绍一下再Apache下的Tomcat负载均衡的一些使用问题

    在负载均衡技术中,硬件设备是比较昂贵的,对于负载均衡的学习者如果不是在企业中应用或者是学员中学习,很少有机会能碰到实际操作的训练.(http://xz.8682222.com)所以,很多朋友都会选择软 ...

  3. 廖雪峰Java11多线程编程-2线程同步-4wait和notify

    wait和notify synchronized解决了多线程竞争的问题 我们可以在synchronized块中安全的对一个变量进行修改,但是它没有解决多线程协调的问题. 例如设计一个TaskQueue ...

  4. 关于操作系统中英文切换的.po和.mo介绍

    一.文件简介 .po文件,.mo文件,.pot文件是由gettext程序生成或者使用的源代码和编译结果.   1..pot文件  是一种模板文件,其实质与.po文件一样,其中包含了从源代码中提取所有的 ...

  5. Java写爬虫代码时报org.apache.http.client.ClientProtocolException: URI does not specify a valid host异常的处理

    异常原因是url写错,导致无法解析 比如:这个报错就是因为写了两个“http:”导致该无法解析

  6. sde中导入shp报错

    在向sde中的数据集导入shp数据,发现报如下错误:

  7. day 45 前端CSS

      前端CSS   CSS介绍 CSS(Cascading Style Sheet,层叠样式表)定义如何显示HTML元素,给HTML设置样式,让它更加美观. 当浏览器读到一个样式表,它就会按照这个样式 ...

  8. 解决pycharm安装python库报错问题

    最近在玩微信图灵机器人,不过我安装有一些库,安装报错,上网找了很久,总结有两种方法,记录一下 方法一: 手动安装,直接到官网你需要的python库下载到本地, 放在安装python路径,C:\User ...

  9. scrapy中使用LinkExtractor提取链接

    le = LinkExtractor(restrict_css='ul.pager li.next') links = le.extract_links(response)   使用LinkExtra ...

  10. PKU 百炼OJ 奖学金

    http://bailian.openjudge.cn/ss2017/A/ #include<iostream> #include <cmath> #include <m ...