PHP服务器文件管理器开发小结(九):jQuery动态表单实现文件下载
前文讨论的文件操作,无论是新建、编辑、移动、删除,都是服务端对本地文件系统的操作。这一节需要讨论一个涉及服务端和客户端协调进行的操作:文件下载。
简单的文件下载可以通过将相对路径写入超链接的方式进行,然而这样仅限于服务端Apache有下载权限的文档,如果需要支持对更多文件进行下载,仅仅使用这一方式就远远不够了。这里需要利用PHP的能力,在服务端“取出”文件并“推送”给客户端。
首先是生成下载图标链接:
1
|
if ( is_readable ( $filePath )) $info .= "<li><a href=\"#\" title=\"download\" onClick=\"onDownload('$filePath')\"><img src=\"images/download32.png\" alt=\"\" class=\"tabmenu\"/></a></li>" ; |
这里之所以使用onDownload而不是前文的onElemAct,是为了强调此处不需要jQueryUI的前端提示。当远程文件被推送到本地后,会直接在浏览器中形成下载提示。
由于要利用浏览器默认的文件下载行为,因此需要使用表单而不是jQuery的Ajax系统,因为不用处理返回数据。然而,这个表单应该是对客户隐形的,因此考虑用jQuery动态生成表单:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
function onDownload(strFilePath) { var formDownload=$( "<form>" ); formDownload.attr( "id" , "frmDownload" ); formDownload.attr( "style" , "display:none" ); formDownload.attr( "target" , "_self" ); formDownload.attr( "method" , "post" ); formDownload.attr( "action" , "query.php" ); var inputDownloadAct=$( "<input>" ); inputDownloadAct.attr( "type" , "hidden" ); inputDownloadAct.attr( "name" , "act" ); inputDownloadAct.attr( "value" , "download" ); var inputDownloadFile=$( "<input>" ); inputDownloadFile.attr( "type" , "hidden" ); inputDownloadFile.attr( "name" , "file" ); inputDownloadFile.attr( "value" , strFilePath); $( "body" ).append(formDownload); formDownload.append(inputDownloadAct); formDownload.append(inputDownloadFile); formDownload.submit(); formDownload.remove(); } |
这里将表单的target指向_self,这样就不会弹出额外的窗口。利用append将表单填充到页面body的尾部,用submit提交表单后,再用remove删除表单。注意这里使用的post请求,对应的act是download,name是文件路径。
PHP接收该请求后,需要生成文件下载报文,将文件的内容填充到报文中。
1
2
3
4
5
6
7
8
9
10
11
|
case "download" : $isDirContentView = false; if (isset( $_POST [ "file" ])) { $filePath = urldecode( $_POST [ "file" ]); header( "Content-Type: application/octet-stream" ); header( "content-disposition: attachment;filename=" . basename ( $filePath )); header( "content-length:" . filesize ( $filePath )); readfile( $filePath ); } break ; |
这里,使用header函数添加额外的报头,使得报文符合合适的下载报文格式。其中重要的是为Content-Type指定合适的值,才能使浏览器正确分析该报文。具体值的选择可以参考对照表。
将文件长度写到content-length中,然后使用readfile将文件内容读取到响应报文中。同时,将$isDirConentView置为false以避免多余的文件输出。
下面是具体效果:
值得注意的是,如果使用迅雷之类下载工具捕获这一下载请求的话,其会将POST请求该为GET请求,并使得请求内容不可控。因此本节提供的方法仅适用于使用浏览器直接下载的情况。
最新文章
- Android开发之补间动画、XML方式定义补间动画
- 常用js函数整理--common.js
- Python学习二---字符串
- POI取消科学计数法
- java 死锁及解决
- 生成html文件
- Javascript多线程引擎(五)
- iOS网络编程笔记——编写自己的网络客户端
- spring data jpa 学习笔记
- 关于python环境配置的博客收藏
- 下载chrome插件和离线安装CRX文件的方法
- 查出了a表,然后对a表进行自查询,a表的别名t1,t2如同两张表,因为t1,t2查询的条件不一样,真的如同两张表,关联两张表,可以将两行或者多行数据合并成一行,不必使用wm_concat()函数。为了将t2表的数据全部查出来使用了右连接。
- 工厂模式-Spring的InitializingBean实现
- DOM的基本操作
- maven profile 多环境
- JSPatch - 基本使用和学习
- 双11怎么那么强!之二:浅析淘宝网络通信库tbnet的实现
- Python练习-sys.argv的无聊用法
- 在控制台连接oracle
- sql server 保留小数,向上保留指定位数的小数,仅记录,勿看。
热门文章
- Android中pull解析XML文件的简单使用
- go语言的第一个helloworld
- 【转】手把手教你用Strace诊断问题
- IDEA内嵌Jetty启动SpringMvc项目
- [学习笔记]通过open函数改变标准输出的方法
- 查询sql语句的执行时间
- SuperSocket1.6电子书离线版
- 在Android中使用FlatBuffers(中篇)
- c++位运算符 | &; ^ ~ &;&; ||,补码,反码
- Android - AndroidStudio 的熟悉