基于jQuery的ajax系列之用FormData实现页面无刷新上传

接着上一篇ajax系列之用jQuery的ajax方法向服务器发出get和post请求写,这篇主要写如何利用ajax和FormData实现页面无刷新的文件上传效果,主要用到了jQuery的ajax()方法和XMLHttpRequest Level 2的FormData接口。关于FormData,大家可以看MDN文档。

1,先看效果图

期望的功能和效果很简单:点击页面中的上传文件表单控件,选择文件后点击“ajax提交”,将文件上传至服务器,上传成功后,页面给出一个简单的提示。

2,前端的代码

看下html代码:

复制代码
 1         <div class="box">2             <div>3                 <div class="item">4                     <input type="file" name="myfile" style="font-size: 0.7rem;">5                 </div>6                 <div class="item">7                     <button type="button" style="display: block; padding: 4px 18px;" class="btn-default">ajax提交</button>8                 </div>9                 <div class="item">
10                     <button type="submit" style="display: block; padding: 4px 18px;" class="btn-default">form提交</button>
11                 </div>
12             </div>
13             <div class="prompt" style="font-size: 0.7rem;"></div>
14         </div>
15         <script src="../../js/jquery-3.1.0.min.js"></script>
16         <script src="upload01.js"></script>
复制代码

代码很简单,需要注意的是页面中没有用到form表单,那么怎么提交数据呢,答案是用FormData来模拟表单中的 <input type="file"name="myfile"> 控件。另外,页面中的样式没有写出来。下面来看下html中引入的upload01.js代码,这个是重点。

upload01.js代码:

复制代码
 1 $(function($) {2     $('input[name=myfile]').on('change', function(e) {3         $('button[type=button]').on('click', function(e) {4             var formData = new FormData();5             // formData.ppend(name, element);6             formData.append('myfile', $('input[name=myfile]')[0].files[0]);7             $.ajax({8                 url: 'upload01.php',9                 method: 'POST',
10                 data: formData,
11                 contentType: false, // 注意这里应设为false
12                 processData: false,
13                 cache: false,
14                 success: function(data) {
15                     if (JSON.parse(data).result == 1) {
16                         $('.prompt').html(`文件${JSON.parse(data).filename}已上传成功`);
17                     }
18                 },
19                 error: function (jqXHR) {
20                     console.log(JSON.stringify(jqXHR));
21                 }
22             })
23             .done(function(data) {
24                 console.log('done');
25             })
26             .fail(function(data) {
27                 console.log('fail');
28             })
29             .always(function(data) {
30                 console.log('always');
31             });
32         });
33     });
34 });
复制代码

 

(1) 下面解释下FormData,涉及到了代码的第4、6、10行。

第4行 var formData = new FormData(); 实例化了一个空的FormData对象,可以认为它就是一个form表单,但现在里面什么控件都没有。

第6行 formData.append('myfile', $('input[name=myfile]')[0].files[0]); ,给实例化的formdata对象添加一个控件,注意这里添加的是已有控件 <input type="file" name="myfile" style="font-size: 0.7rem;"> (见html代码第4行)。

FormData.append(name, value, filename)方法可以很方便的以“键-值”对的形式给FormData添加控件,注意第3个参数“上传文名”是可选的,它的具体语法和用法见FormData。

第10行,将实例化的formData作为jQuery.ajax()方法data参数的值传递进去,提交给后端服务器。

(2) 再解释下ajax()方法中的contentType、processData参数。

contentType参数,发起http请求时设置的请求头中的contentType。jQuery.ajax()默认的值为:'application/x-www-form-urlencoded; charset=UTF-8',这个在大多数情况下都是适用的。

但经过测试,保持默认时会报错,因为发送的数据中有input type="file"(上传文件),那么这时contentType应该设置为'multipart/form-data',但如果指定为这个类型服务端(php)就会报这个错误: Warning: Missing boundary in multipart/form-data POST data in Unknown on line 0 。具体原因现在还不清楚,所以这里先将contentType设置为false,即不让jQuery设置contentType。

processData参数,根据jQuery.ajax()文档中的解释,默认情况下,jQuery会处理发送的数据,将数据按照'application/x-www-form-urlencoded'的要求转换为查询字符串,如果要发送的数据是DOMDocument或者不需要处理,就可以设置为false不让jQuery转换数据,我们这里要发送的数据其实就是DOMDocument。

经过测试,如果保持默认(true)的话,在发起请求前js会报错: TypeError: 'append' called on an object that does not implement interface FormData. 

另外还有个dataType参数,期望从服务器中返回的数据格式,这里最好也不要指定,而是让jquery自己根据http响应头中的contentType判断,然后返回一个合适的数据类型。指定后不会影响后台程序的逻辑处理,但你在前端接收的数据很可能不是期望的数据,于是js就会报这一类错误: SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data ,这个是将dataType指定为json后报的错误。

3,后端的php代码

后端服务器是nginx,用php来处理发送过来的数据,代码也很简单:

 

复制代码
 1 <?php2 // var_dump($_REQUEST); // 为空数组3 // var_dump($_FILES); //不为空4 5 // 当使用FormData配合ajax上传文件时,$_REQUEST、$_POST都是null,php://input也是null6 if (isset($_FILES) && !empty($_FILES)) {7     if (move_uploaded_file($_FILES['myfile']['tmp_name'], $_FILES['myfile']['name'])) {8         echo '{"result": 1, "filename": "' . $_FILES['myfile']['name'] . '"}';9     } else {
10         echo '{"result": 0}';
11     }
12 }
复制代码

 

代码的逻辑很简单这里就不多解释了。主要说下我在调试程序时遇到的问题,遇到的问题总结起来就一句话:当使用FormData配合ajax上传文件时,$_REQUEST、$_POST都是空数组,php://input也是null。可以看到,我在代码中的第2、3、5行也写了相关的注释。为什么$_REQUEST会是空呢?我查了些资料,但没找到原因,以后再找原因吧。

 

参考资料:

jQuery.ajax()

FormData

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/291701.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux网络编程之用多线程实现客户端到服务端的通信(基于udp)

1、开启一个线程接受数据,主线程发送数据的代码 #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <netinet/in.h> #include <errno.h> #include <sys/time.h&g…

Apache FTPClient操作文件上传下载及公共类

我们在项目中可能需要使用ftp进行文件的上传、下载、获取服务器目录信息等相关操作&#xff0c;我们可以使用apache的FTPClient进行相关的操作&#xff0c;下面把相关公共方法与大家交流分享&#xff0c;每个方法前都有详细的注释进行讲解&#xff0c;不过在进行ftp测试的时候&…

abd shell关闭所有程序_在后台服务器上运行程序

之前总结过screen的用法&#xff0c;但还可以用nohup命令。nohup工具&#xff1a;Linux系统中有提供一个很好的不挂断地运行命令——nohup。我们使用nohup能很简单的控制使用&#xff0c;在此就简单的介绍一下nohup工具。nohup 命令nohup就是不挂起的意思( no hang up)。用途&a…

优秀的JavaScript模块是怎样炼成的

引言&#xff1a;如今的JavaScript已经是Web上最流行的语言&#xff0c;没有之一。从Github上的语言排行榜https://github.com/languages上即可看出&#xff0c;也是如今最为活跃的开源社区。随着Node的加入&#xff0c;JavaScript开枝散叶进入服务器领域&#xff0c;为这个语言…

解锁JDK 12的奇妙之旅:新特性详解

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 解锁JDK 12的奇妙之旅&#xff1a;新特性详解 前言switch表达式拓展NumberFormat对复杂数字的格式化字符串支持transform、indent操作新增方法Files.mismatch(Path, Path)Teeing Collector支持unicode…

.NET6之MiniAPI(十四):跨域CORS(上)

为了说明跨请求&#xff0c;创建了两个项目&#xff0c;一个mini api&#xff0c;端口是5001&#xff0c;另一个razor page项目&#xff0c;端口是5280。5280项目会在页面用ajax的方式来请求5001&#xff0c;形成跨域请求&#xff0c;由于是本地测试&#xff0c;host都是localh…

Linux文件锁学习-flock, lockf, fcntl

参考 linux中fcntl()、lockf、flock的区别 这三个函数的作用都是给文件加锁&#xff0c;那它们有什么区别呢&#xff1f; 首先flock和fcntl是系统调用&#xff0c;而lockf是库函数。lockf实际上是fcntl的封装&#xff0c;所以lockf和fcntl的底层实现是一样的&#xff0c;对文件…

linux网络编程之sockaddr_in和in_addr区别

1、struct in_addr struct in_addr就是32位IP地址。 struct in_addr { union {struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;struct { u_short s_w1,s_w2; } S_un_w;u_long S_addr;} S_un;#define s_addr S_un.S_addr }; 2、sockaddr_in struct sockaddr_in …

入驻

新手登录~

django model filter 条件过滤,及多表连接查询、反向查询,某字段的distinct

2019独角兽企业重金招聘Python工程师标准>>> 1.多表连接查询&#xff1a;当我知道这点的时候顿时觉得django太NX了。 class A(models.Model): name models.CharField(u名称) class B(models.Model): aa models.ForeignKey(A)B.objects.filter(aa__name__c…

利用tabluea分析数据的案例_利用德温特分析Dartsip的案例检索结果

德温特创新平台(Derwent Innovation)与Darts-ip知识产权案例数据库均是科睿唯安旗下的知识产权数据库&#xff0c;虽然这两个数据库的侧重点分别在于专利信息与知识产权判例&#xff0c;但若将两者结合使用则能发挥11>2的作用&#xff0c;打通专利全生命周期。关注我们的朋友…

浅谈C#可变参数params

前言前几天在群里看到群友写了一个基础框架&#xff0c;其中涉及到关于同一个词语可以添加多个近义词的一个场景。当时群友的设计是类似字典的设计&#xff0c;直接添加k-v的操作&#xff0c;本人看到后思考了一下觉得使用c#中的params可以更优雅的实现一个key同时添加一个集合…

Html、Css-----当有文字和图片的时候,需要文字和图片居中,怎么实现?不想文字换行怎么设置...

1 当有文字和图片的时候&#xff0c;需要文字和图片居中&#xff0c;怎么实现&#xff1f; <a href#" target"aa" style"white-space:nowrap;"><img src"img.jpg" align"absmiddle"/>文字</a> 在img标签中加入…

linux网络编程之怎么配置好unp.h文件

1、获取unp源码 下载地址:http://www.unpbook.com/src.html 然后用tar -zxvf unpv13e.tar.gz命令解压 2、进入unpv13e目录执行configure cd unpv13e ,然后执configure文件 3、打开README文件,使用make命令 打开README文件

Win10下安装wireshark不能正常使用,cmd管理员身份调用net start npf命令显示无法启动该服务

我安装wireshark完成后&#xff0c;刚开始运行wireshark并开始捕获时也不能正常捕获&#xff0c;然后发现是winpcap的原因。 我把我安装的wireshark版本和winpcap的版本资源和我个人出现问题的解决办法及经验已打包上传资源&#xff0c;伙伴们有需要的可以去参考借鉴一下~ PS…

CMD、AMD、commonJs 规范的写法

比较好的文章&#xff1a; http://www.jianshu.com/p/d67b...AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。 //AMD 规范 /*** define(id?, dependencies?, factory); id 和 dependencies 是可选的。** define([d…

mft文件记录属性头包括_关于NTFS-MFT

一、Ntfs文件系统在磁盘上的分布一个ntfs文件系统由引导扇区、MFT(包含MFT元数据)和数据区组成。NTFS中存储了两份MFT备份以防MFT文件损坏&#xff0c;两个MFT备份的具体起始位置都存储在引导扇区中。image.png二、引导扇区($Boot)引导扇区是从NTFS文件系统的第一个扇区开始&am…

ffmpeg avformat_open_input返回失败的解决办法

用ffmpeg做的第一个程序&#xff0c;参考网上的代码&#xff0c;就出现了一些问题&#xff0c;其中avformat_open_input返回失败。 下面是我在网上收集到的失败信息的相关解决&#xff1a; 很多朋友在使用新版本的ffmpeg时&#xff0c;都遇到了avformat_open_input返回失败的问…

客户端禁用Keep-Alive, 服务端开启Keep-Alive,会怎么样?

最近部署的web程序&#xff0c;服务器上出现不少time_wait的tcp连接状态&#xff0c;占用了tcp端口&#xff0c;花费几天时间排查。之前我有结论&#xff1a;HTTP keep-alive 是在应用层对TCP连接的滑动续约复用&#xff0c;如果客户端、服务器稳定续约&#xff0c;就成了名副其…

linux网络编程之一般应用采用的协议和不同套接字的地址结构以及用户进程和内核通过哪些函数传递套接字的地址结构

1、一般应用采用的协议 2、不同套接字的地址结构 3、用户进程和内核通过哪些函数传递套接字的地址结构 从进程到内核传递套接字的地址结构函数有3个 bind、connect、sendto函数 从内核到进程传递套接字的地址结构函数有4个函数 accept、recvfrom 、getsockname 、getpeername…