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 相关文章推荐
json+jQuery实现的无限级树形菜单效果代码
Aug 27 Javascript
ES6中如何使用Set和WeakSet
Mar 10 Javascript
JS获取IMG图片高宽的简单实例
May 17 Javascript
微信小程序 闭包写法详细介绍
Dec 14 Javascript
JavaScript Canvas绘制圆形时钟效果
Aug 20 Javascript
老生常谈js-react组件生命周期
May 02 Javascript
详解Vue组件之间的数据通信实例
Jun 17 Javascript
原生JS+Canvas实现五子棋游戏实例
Jun 19 Javascript
微信小程序实现点击按钮修改字体颜色功能【附demo源码下载】
Dec 05 Javascript
swiper自定义分页器使用方法详解
Sep 14 Javascript
用node-webkit把web应用打包成桌面应用(windows环境)
Feb 01 Javascript
说说Vue.js中的functional函数化组件的使用
Feb 12 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面向对象的进阶学习(抽像类、接口、final、类常量)
2012/05/07 PHP
yii实现创建验证码实例解析
2014/07/31 PHP
PHP递归遍历指定目录的文件并统计文件数量的方法
2015/03/24 PHP
PHP自动生成表单代码分享
2015/06/19 PHP
Yii2框架数据验证操作实例详解
2018/05/02 PHP
Laravel 前端资源配置教程
2019/10/18 PHP
PHP发送邮件确认验证注册功能示例【修改别人邮件类】
2019/11/09 PHP
JS解析XML的实现代码
2009/11/12 Javascript
Jquery实现无刷新DropDownList联动实现代码
2010/03/08 Javascript
JQuery 拾色器插件发布-jquery.icolor.js
2010/10/20 Javascript
基于jQuery倾斜打开侧边栏菜单特效代码
2015/09/15 Javascript
ajax在兼容模式下失效的快速解决方法
2016/03/22 Javascript
javascript另类方法实现htmlencode()与htmldecode()函数实例分析
2016/11/17 Javascript
jQuery事件绑定方法学习总结(推荐)
2016/11/21 Javascript
JS百度地图搜索悬浮窗功能
2017/01/12 Javascript
es6基础学习之解构赋值
2018/12/10 Javascript
Vue起步(无cli)的啊教程详解
2019/04/11 Javascript
python实现模拟按键,自动翻页看u17漫画
2015/03/17 Python
Python实现文件按照日期命名的方法
2015/07/09 Python
python环形单链表的约瑟夫问题详解
2018/09/27 Python
Pandas过滤dataframe中包含特定字符串的数据方法
2018/11/07 Python
Python 处理图片像素点的实例
2019/01/08 Python
python实现的多任务版udp聊天器功能案例
2019/11/13 Python
PyTorch实现更新部分网络,其他不更新
2019/12/31 Python
tensorboard实现同时显示训练曲线和测试曲线
2020/01/21 Python
什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?
2016/08/13 面试题
linux下进程间通信的方式
2014/12/23 面试题
高三毕业生自我鉴定
2013/12/20 职场文书
消防宣传口号
2014/06/16 职场文书
个人主要事迹材料
2014/08/26 职场文书
教育局党的群众路线教育实践活动整改方案
2014/09/20 职场文书
golang import自定义包方式
2021/04/29 Golang
使用redis实现延迟通知功能(Redis过期键通知)
2021/09/04 Redis
用Python爬取英雄联盟的皮肤详细示例
2021/12/06 Python
Redis安装使用RedisJSON模块的方法
2022/03/23 Redis
解决Springboot PostMapping无法获取数据的问题
2022/05/06 Java/Android