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 相关文章推荐
XHTML下,JS浮动代码失效的问题
Nov 12 Javascript
Js判断参数(String,Array,Object)是否为undefined或者值为空
Nov 04 Javascript
jQuery实现炫酷的鼠标轨迹特效
Feb 01 Javascript
一道优雅面试题分析js中fn()和return fn()的区别
Jul 05 Javascript
angular+ionic 的app上拉加载更新数据实现方法
Jan 16 Javascript
浅析vue深复制
Jan 29 Javascript
微信小程序开发之路由切换页面重定向问题
Sep 18 Javascript
vue中当图片地址无效的时候,显示默认图片的方法
Sep 18 Javascript
小程序指纹验证的实现代码
Dec 04 Javascript
AngularJS动态生成select下拉框的方法实例
Nov 17 Javascript
JavaScript实现指定数量的并发限制的示例代码
Mar 10 Javascript
使用纯前端JavaScript实现Excel导入导出方法过程详解
Aug 07 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
php5 apache 2.2 webservice 创建与配置(java)
2011/01/27 PHP
PHPAnalysis中文分词类详解
2014/06/13 PHP
php在windows环境下获得cpu内存实时使用率(推荐)
2018/02/08 PHP
JS动态增加删除UL节点LI及相关内容示例
2014/05/21 Javascript
javascript中错误使用var造成undefined
2016/03/31 Javascript
jQuery实现鼠标跟随提示层效果代码(可显示文本,Div,Table,Html等)
2016/04/18 Javascript
JS组件系列之使用HTML标签的data属性初始化JS组件
2016/09/14 Javascript
详解vue-Resource(与后端数据交互)
2017/01/16 Javascript
AngularJS实现的JSONP跨域访问数据传输功能详解
2017/07/20 Javascript
Vue.js实现网格列表布局转换方法
2017/08/25 Javascript
浅谈ES6 模板字符串的具体使用方法
2017/11/07 Javascript
对vue 键盘回车事件的实例讲解
2018/08/25 Javascript
JS对日期操作封装代码实例
2019/11/08 Javascript
[10:18]2018DOTA2国际邀请赛寻真——找回自信的TNCPredator
2018/08/13 DOTA
[00:43]拉比克至宝魔导师密钥展示
2018/12/20 DOTA
Python threading多线程编程实例
2014/09/18 Python
python测试驱动开发实例
2014/10/08 Python
用Python操作字符串之rindex()方法的使用
2015/05/19 Python
一波神奇的Python语句、函数与方法的使用技巧总结
2015/12/08 Python
Centos7 Python3下安装scrapy的详细步骤
2018/03/15 Python
win7+Python3.5下scrapy的安装方法
2018/07/31 Python
Pandas读取并修改excel的示例代码
2019/02/17 Python
python itchat给指定联系人发消息的方法
2019/06/11 Python
python适合人工智能的理由和优势
2019/06/28 Python
关于Python解包知识点总结
2020/05/05 Python
Django Path转换器自定义及正则代码实例
2020/05/29 Python
解决pycharm debug时界面下方不出现step等按钮及变量值的问题
2020/06/09 Python
Ratchet 模态框的实现
2020/08/19 HTML / CSS
StubHub巴西:购买和出售您的门票
2016/07/22 全球购物
Nike法国官方网站:Nike.com FR
2018/07/22 全球购物
德国黑胶唱片、街头服装及运动鞋网上商店:HHV
2018/08/24 全球购物
英国DIY和家居装饰领域的主要品牌:Wickes
2019/11/26 全球购物
安全标准化汇报材料
2014/02/03 职场文书
小学教师师德反思
2014/02/03 职场文书
企业人事任命书
2014/06/05 职场文书
2015年城管个人工作总结
2015/05/15 职场文书