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

简单的文件下载可以通过将相对路径写入超链接的方式进行,然而这样仅限于服务端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. 【总结整理】display、visibility、overflow的隐藏问题

    display.visibility.overflow的隐藏问题 http://blog.sina.com.cn/s/blog_85e7c239010151r4.html   display:bloc ...

  2. UITextField的文本框部分文本以*的方式来显示

    #import "AppDelegate.h" @interface AppDelegate ()<UITextFieldDelegate>// 添加代理协议 @end ...

  3. Python Matplotlib.plot Update image Questions

    1. 最近在测试一款设备,采集了一些设备后需要一帧一帧显示图像,经常使用Python,所以选用了Matplotlib进行图像操作 数据结构: timesatamp polar_distance hor ...

  4. 算法Sedgewick第四版-第1章基础-1.4 Analysis of Algorithms-003定理

    1. 2. 3. 4. 5. 6.

  5. Linux 控制台/终端/tty/shell

    一.简介 使用linux已经有一段时间,却一直弄不明白这几个概念之间的区别.这些概念本身有着非常浓厚的历史气息,随着时代的发展,他们的含义也在发生改变,它们有些已经失去了最初的含义,但是它们的名字却被 ...

  6. 使用 classList API

    一.classList API 是什么 属于 DOM API,HTML5 引入,用来操作 HTML 标签的 class 属性值. classList 属性是一个只读的类数组对象,"实时&qu ...

  7. .net中值类型、引用类型理解的c#代码示例

    下面是以前在公司的时候给别人讲解值类型.引用类型时创建的c#代码示例,从实际使用时的角度出发,对于初学者还是很有帮助的.这里并没有深入讲解值类型包含引用类型成员时(如struct)在内存中的存放情况等 ...

  8. dubbo异步调用原理 (1)

    此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 一.使用方式 服务提供方不变,调用方代码如下: 1     <dubbo:reference id=& ...

  9. 利用excel制作二维码

    1 将想要通过扫描二维码访问的目标网址放入A1单位格 2 在excel 编辑区右击选择“自定义功能区” 3 然后将“开发者工具”选上 4 点击菜单栏的“开发者工具---插入--->其他控件” 5 ...

  10. 【LeetCode每天一题】Remove Duplicates from Sorted List(移除有序链表中的重复数字)

    Given a sorted linked list, delete all duplicates such that each element appear only once. Example 1 ...