jQuery的ajax中使用FormData实现页面无刷新上传功能


Posted in Javascript onJanuary 16, 2017

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

1,先看效果图

jQuery的ajax中使用FormData实现页面无刷新上传功能

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

2,前端的代码

看下html代码:     

<div class="box">
    <div>
     <div class="item">
      <input type="file" name="myfile" style="font-size: 0.7rem;">
     </div>
     <div class="item">
      <button type="button" style="display: block; padding: 4px 18px;" class="btn-default">ajax提交</button>
     </div>
     <div class="item">
      <button type="submit" style="display: block; padding: 4px 18px;" class="btn-default">form提交</button>
     </div>
    </div>
    <div class="prompt" style="font-size: 0.7rem;"></div>
   </div>
   <script src="../../js/jquery-3.1.0.min.js"></script>
   <script src="upload01.js"></script>

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

upload01.js代码:

$(function($) {
  $('input[name=myfile]').on('change', function(e) {
   $('button[type=button]').on('click', function(e) {
    var formData = new FormData();
    // formData.ppend(name, element);
    formData.append('myfile', $('input[name=myfile]')[0].files[0]);
    $.ajax({
     url: 'upload.php',
     method: 'POST',
     data: formData,
     contentType: false, // 注意这里应设为false
     processData: false,
     cache: false,
     success: function(data) {
     if (JSON.parse(data).result == 1) {
       $('.prompt').html(`文件${JSON.parse(data).filename}已上传成功`);
      }
     },
     error: function (jqXHR) {
      console.log(JSON.stringify(jqXHR));
     }
    })
    .done(function(data) {
     console.log('done');
    })
    .fail(function(data) {
     console.log('fail');
    })
    .always(function(data) {
     console.log('always');
    });
   });
  });
 });

(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来处理发送过来的数据,代码也很简单:

<?php
 // var_dump($_REQUEST); // 为空数组
 // var_dump($_FILES); //不为空 
 // 当使用FormData配合ajax上传文件时,$_REQUEST、$_POST都是null,php://input也是null
 if (isset($_FILES) && !empty($_FILES)) {
  if (move_uploaded_file($_FILES['myfile']['tmp_name'], $_FILES['myfile']['name'])) {
   echo '{"result": 1, "filename": "' . $_FILES['myfile']['name'] . '"}';
  } else {
   echo '{"result": 0}';
  }
 }

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

以上所述是小编给大家介绍的jQuery的ajax中使用FormData实现页面无刷新上传功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
DOM 脚本编程中的兄弟节点
Oct 31 Javascript
window.event快达到全浏览器支持了,以后使用就方便了
Nov 30 Javascript
jquery事件机制扩展插件 jquery鼠标右键事件。
Dec 26 Javascript
把字符串按照特定的字母顺序进行排序的js代码
Jan 28 Javascript
网络传输协议(http协议)
Nov 18 Javascript
bootstrap多种样式进度条展示
Dec 20 Javascript
JS中IP地址与整数相互转换的实现代码
Apr 10 Javascript
使用JQ完成表格隔行换色的简单实例
Aug 25 Javascript
Angular自定义组件实现数据双向数据绑定的实例
Dec 11 Javascript
React通过redux-persist持久化数据存储的方法示例
Feb 14 Javascript
layui数据表格 table.render 报错的解决方法
Sep 29 Javascript
JavaScript实现电灯开关小案例
Mar 30 Javascript
Node.js中用D3.js的方法示例
Jan 16 #Javascript
JavaScript实现的select点菜功能示例
Jan 16 #Javascript
使用AngularJS 跨站请求如何解决jsonp请求问题
Jan 16 #Javascript
JavaScript基于DOM操作实现简单的数学运算功能示例
Jan 16 #Javascript
js实现弹窗暗层效果
Jan 16 #Javascript
js实现简单的计算器功能
Jan 16 #Javascript
Javascript中document.referrer隐藏来源的方法
Jan 16 #Javascript
You might like
php检测图片木马多进制编程实践
2013/04/11 PHP
PHP面向对象程序设计之对象生成方法详解
2016/12/02 PHP
PHP简单实现解析xml为数组的方法
2018/05/02 PHP
PHP写API输出的时用echo的原因详解
2019/04/28 PHP
疯掉了,尽然有js写的操作系统
2007/04/23 Javascript
JSQL 批量图片切换的实现代码
2010/05/05 Javascript
关于jQuery $.isNumeric vs. $.isNaN vs. isNaN
2013/04/15 Javascript
jquery实现ajax提交form表单的方法总结
2014/03/03 Javascript
jquery使用slideDown实现模块缓慢拉出效果的方法
2015/03/27 Javascript
jquery mobile 移动web(5)
2015/12/20 Javascript
Js的Array数组对象详解
2016/02/22 Javascript
jquery ajax双击div可直接修改div中的内容
2016/03/04 Javascript
jQuery使用正则表达式替换dom元素标签用法示例
2017/01/16 Javascript
JS操作input标签属性checkbox全选的实现代码
2017/03/02 Javascript
Js实现京东无延迟菜单效果实例(demo)
2017/06/02 Javascript
JS实现基于Sketch.js模拟成群游动的蝌蚪运动动画效果【附demo源码下载】
2017/08/18 Javascript
移动端H5页面返回并刷新页面(BFcache)的方法
2018/11/06 Javascript
通过JQuery,JQueryUI和Jsplumb实现拖拽模块
2019/06/18 jQuery
Node.js安装详细步骤教程(Windows版)详解
2019/09/01 Javascript
基于js实现数组相邻元素上移下移
2020/05/19 Javascript
用Python的Django框架编写从Google Adsense中获得报表的应用
2015/04/17 Python
在Python中使用cookielib和urllib2配合PyQuery抓取网页信息
2015/04/25 Python
Python实现扫描局域网活动ip(扫描在线电脑)
2015/04/28 Python
Python的Flask框架中集成CKeditor富文本编辑器的教程
2016/06/13 Python
利用Python破解斗地主残局详解
2017/06/30 Python
pandas 对group进行聚合的例子
2019/12/27 Python
代码总结Python2 和 Python3 字符串的区别
2020/01/28 Python
tensorflow实现残差网络方式(mnist数据集)
2020/05/26 Python
python中执行smtplib失败的处理方法
2020/07/01 Python
HTML+CSS3模拟心的跳动实例代码
2017/09/05 HTML / CSS
材料成型专业个人求职信范文
2013/09/25 职场文书
大学生学习党课思想汇报
2014/01/03 职场文书
县政府办公室领导班子对照检查材料思想汇报
2014/09/28 职场文书
Redis中有序集合的内部实现方式的详细介绍
2022/03/16 Redis
阿里云 Windows server 2019 配置FTP
2022/04/28 Servers
centos环境下nginx高可用集群的搭建指南
2022/07/23 Servers