前文讨论的文件操作,无论是新建、编辑、移动、删除,都是服务端对本地文件系统的操作。这一节需要讨论一个涉及服务端和客户端协调进行的操作:文件下载。

简单的文件下载可以通过将相对路径写入超链接的方式进行,然而这样仅限于服务端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请求,并使得请求内容不可控。因此本节提供的方法仅适用于使用浏览器直接下载的情况。

PHP服务器文件管理器开发小结(九):jQuery动态表单实现文件下载的更多相关文章

  1. python运维开发(十九)----Django后台表单验证、session、cookie、model操作

    内容目录: Django后台表单验证 CSRF加密传输 session.cookie model数据库操作 Django后台Form表单验证 Django中Form一般有2种功能: 1.用于做用户提交 ...

  2. jQuery formValidator表单验证插件

    什么是jQuery formValidator? jQuery formValidator表单验证插件是客户端表单验证插件. 在做B/S开发的时候,我们经常涉及到很多表单验证,例如新用户注册,填写个人 ...

  3. ASP.NET MVC Jquery Validate 表单验证的多种方式

    在我们日常开发过程中,前端的表单验证很重要,如果这块处理不当,会出现很多bug .但是如果处理的好,不仅bug会很少,用户体验也会得到很大的提升.在开发过程中我们可以不借助 JS 库,自己去手写 JS ...

  4. jQuery Mobile 表单基础

    jQuery Mobile 会自动为 HTML 表单添加优异的便于触控的外观. jQuery Mobile 表单结构 jQuery Mobile 使用 CSS 来设置 HTML 表单元素的样式,以使其 ...

  5. [转]ASP.NET MVC Jquery Validate 表单验证的多种方式介绍

    在我们日常开发过程中,前端的表单验证很重要,如果这块处理不当,会出现很多bug .但是如果处理的好,不仅bug会很少,用户体验也会得到很大的提升.在开发过程中我们可以不借助 JS 库,自己去手写 JS ...

  6. 通过AJAX和PHP,提交JQuery Mobile表单

    File name: callajax.php <?php $firstName = $_POST[firstName]; $lastName = $_POST[lastName]; echo( ...

  7. Jquery Validate 表单验证的多种方式

    ASP.NET MVC Jquery Validate 表单验证的多种方式 在我们日常开发过程中,前端的表单验证很重要,如果这块处理不当,会出现很多bug .但是如果处理的好,不仅bug会很少,用户体 ...

  8. 雷林鹏分享:jQuery EasyUI 表单 - 创建异步提交表单

    jQuery EasyUI 表单 - 创建异步提交表单 本教程向您展示如何通过 easyui 提交一个表单(Form).我们创建一个带有 name.email 和 phone 字段的表单.通过使用 e ...

  9. 雷林鹏分享:jQuery EasyUI 表单 - 创建树形下拉框

    jQuery EasyUI 表单 - 创建树形下拉框 树形下拉框(ComboTree)是一个带有下列树形结构(Tree)的下拉框(ComboBox).它可以作为一个表单字段进行使用,可以提交给远程服务 ...

随机推荐

  1. css知多少(6)——选择器的优先级(转)

    css知多少(6)——选择器的优先级   1. 引言 上一节<css知多少(5)——选择器>最后提到,选择器类型过多将导致一些问题,是什么问题呢?咱们直接举例子说明. 上图中,css中的两 ...

  2. div+css学习笔记一(转)

    div+css学习笔记一 (2011-05-12 07:32:08) 标签: div css 居中 背景图片 ie6 ie7 margin 杂谈 分类: 网页制作 1.IE6中用了float之后导致m ...

  3. 阿里云、宝塔、wordpress建站

    1 阿里云 购买一个学生机就行啦 2 宝塔 2.1 更改阿里云的镜像 技巧01:先关掉阿里云之前的镜像 技巧02:到镜像市场中寻找宝塔的镜像资源 2.2 配置安全组 宝塔的控制面板需要开通端口 888 ...

  4. vray学习笔记(4)混合材质是个什么东西

    看下定义: The Blend material lets you mix two materials on a single side of the surface. Blend material材 ...

  5. 安装Maven及Eclipse中配置Maven

    下载maven版本: 1.进入官网:http://maven.apache.org/download.cgi   ,下载编译后的maven版本:如图下: 2.创建一个目录,把下载的maven压缩包,进 ...

  6. Entity Framework Tutorial Basics(25):Delete Single Entity

    Delete Entity using DBContext in Disconnected Scenario: We used the Entry() method of DbContext to m ...

  7. ubuntu nvidia驱动+cuda9.0

    https://blog.csdn.net/fdqw_sph/article/details/78745375

  8. 美团热更新Robust Demo演示

    1.Android Studio clone 远程Robust项目源码 gradle 同步依赖资源,可能需要半个小时左右. 2.生成样例apk包 配置app module下build.gradle 插 ...

  9. vimrc配置-中文编码和python中的中文注释

    set fileencoding=gb18030"设置vim输入的编码 set fileencodings=gb18030,...,"打开文档时vim自动匹配可能的编码方式 在py ...

  10. GridView内按钮Click获取记录主键值 在GridView控件中,每行记录内会放置一个铵钮,当用

    在GridView控件中,每行记录内会放置一个铵钮,当用户点击这个铵钮时,获取当笔记录的主键值.可看演示(是一个gif动画,重新播放尝试刷新网页): 实现这个功能,你需要为GridView控件设置Da ...