Ajax 笔记

1. 服务器的基本概念与初始 Ajax

1.1 URL 地址

1.1.1 URL 地址的概念

        URL,统一资源定位符,用于标识互联网上每个资源的唯一存放位置。浏览器只有通过 URL 地址,才能正确定位资源的存放位置,从而成功访问到对应的资源。

1.1.2 URL 地址的组成部分

        URL 地址由三部分组成:

(1)客户端与服务器之间的通信协议

(2)存有该资源的服务器名称

(3)资源在服务器上具体的存放位置

1.2 客户端与服务器的通信过程

1.2.1 图解

客户端与服务器的通信过程分为 请求——处理——响应 三个步骤

1.2.2 基于浏览器的开发者工具分析通信过程

1.3 服务器对外提供资源

1.3.1 网页中如何请求数据

        若在网页中请求服务器上的数据资源,则需用到 XMLHttpRequest 对象,它是浏览器提供的 js 成员

        最简单的用法是 var xhrObj   = new XMLHttpRequest()

1.3.2 资源的请求方式

        客户端请求服务器时,最常见的请求方式有 get 和 post 请求

(1)get 请求通常用于获取服务端资源

(2)post 请求通常用于向服务器提交数据

1.4 Ajax 概念

        Ajax 的全称是 Asynchronous JavaScript And XML(异步 JavaScript 和 XML)

        Ajax:在网页中利用 XMLHttpRequest 对象和服务器进行数据交互的方式

1.5 jQuery 中的 Ajax

1.5.1 $.get() 函数

        $.get() 函数向服务器获取数据

(1)基本语法

$.get(url, [data], [callback])    // 中括号代表可选参数

(2)$.get() 发起不带参数的请求

        直接提供请求的 url 地址和请求成功后的回调函数即可

    $(function() {
      $("button").on('click', function() {
        $.get('http://www.liulongbin.top:3006/api/getbooks',function(res) {
          console.log(res);
        })
      })
    })

(3)$.get() 发起带参数的请求

    $(function() {
      $("button").on('click', function() {
        $.get('http://www.liulongbin.top:3006/api/getbooks', {id: 1}, function(res) {
          console.log(res);
        })
      })
    })
        
// 参数要用{}

 

 1.5.2 $.post() 函数

         $.post() 函数向服务器提交数据

(1)基本语法

$.post(url, [data], [callback])    // 中括号代表可选参数

(2) $.post() 向服务器提交数据

    $(function() {
      $("button").on('click', function() {
        $.post('http://www.liulongbin.top:3006/api/addbook', {bookname:'水浒传',author:'施耐庵', publisher:'天津图书出版社'}, function(res) {
          console.log(res);
        })
      })
    })

 

 1.5.3 $,ajax() 函数

(1)基本语法

$.ajax({
    type: '',    // 请求的方式,例如 GET 或者 POST
    url: '',    // 请求的 URL 地址
    data: { },    // 这次请求要携带的数据
    success: function(res) { }    // 请求成功后的回调函数
})

(2)使用 $.ajax() 发起 GET 请求

    $(function() {
      $("button").on('click', function() {
        $.ajax({
          type: 'GET',
          url: 'http://www.liulongbin.top:3006/api/getbooks',
          data: {
            id: 1
          },
          success: function(res) {
            console.log(res)
          }
        })
      })
    })
// 函数中各项用","隔开

(2)使用 $.ajax() 发起 POST 请求 

    $(function() {
      $("button").on('click', function() {
        $.ajax({
          type: 'POST',
          url: 'http://www.liulongbin.top:3006/api/addbook',
          data: {
            bookname: '史记',
            author: '司马迁',
            publisher: '上海图书出版社'
          },
          success: function(res) {
            console.log(res);
          }
        })
      })
    })

 1.6 接口

1.6.1 接口的概念

        使用 Ajax 请求数据时,被请求的 URL 地址,叫做数据接口(简称接口),每个接口必须有请求方式。

例如:

http://www.liulongbin.top:3006/api/getbooks        获取图书的接口(GET 请求)

http://www.liulongbin.top:3006/api/addbook        添加图书的接口(POST 请求)

1.6.2 接口测试工具

1.6.2.1 PostMan 组成部分

1.6.1.2 使用 PostMan 测试 GET 接口

(1)选择请求方式

(2)填写请求的 URL 地址,

(3)选择 Params 填写请求的参数

(3)点击 send 发起请求

(4)查看服务器响应的结果

1.6.1.2 使用 PostMan 测试 POST 接口

(1)选择请求方式

(2)填写请求的 URL 地址

(3)选择 Body 面板并勾选数据格式

(4)填写要发送到服务器的数据

(5)点击 send 发起请求

(6)查看服务器响应的结果

 1.6.3 接口文档

1.6.3.1 概念

        接口文档:接口的说明文档,是调用接口的依据。

1.6.3.2 组成部分

(1) 接口名称:用来标识各个接口的简单说明,如登录接口,获取图书列表接口等

(2)接口 URL :接口的调用地址

(3)调用方式:接口的调用方式,如 GET 或者 POST

(4)参数格式:接口需要传递的参数,每个参数必须包含参数名称、参数类型、是否必选、参数说明这4项内容

(5)响应格式:接口的返回值的详细描述,一般包括数据名称、数据类型、说明这3项内容

(6)返回示例(可选):通过对象的形式,例举服务器返回数据的结构

1.6.3.3 示例

 1.7 案例——图书管理

1.7.1 案例用到的库和插件

        css 库:bootstrap.css

        JavaScript 库:jquery.js

        vs code 插件:Bootstrap 3 Snippets

1.7.2 代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./lib/bootstrap.css">
  <script src="./lib/jquery.js"></script>
</head>
<body style="padding: 15px;">
  <!-- 添加图书的 Panel 面板 -->
  <!-- bs3-panel:primary -->
  <div class="panel panel-primary">
      <div class="panel-heading">
        <h3 class="panel-title">添加新图书</h3>
      </div>
      <div class="panel-body form-inline">  
        <!-- 加上 form-inline 使内容在同一行中 -->
        <!-- bs3-input-group:addon:text -->
        
        <div class="input-group">
          <div class="input-group-addon">书名</div>
          <input type="text" class="form-control" id="iptBookname" placeholder="请输入书名">
        </div>
        
        <div class="input-group">
          <div class="input-group-addon">作者</div>
          <input type="text" class="form-control" id="iptAuthor" placeholder="请输入作者">
        </div>

        <div class="input-group">
          <div class="input-group-addon">出版社</div>
          <input type="text" class="form-control" id="iptPublisher" placeholder="请输入出版社">
        </div>

        <button id="btnAdd" class="btn btn-primary">添加</button>
      </div>
  </div>
  
  <!-- 图书的表格 -->
  <!-- bs3-table:bordered -->
  <table class="table table-bordered table-hover">
    <thead>
      <tr>
        <th>Id</th>
        <th>书名</th>
        <th>作者</th>
        <th>出版社</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody id="tb"></tbody>
  </table>
  
  <script>
    $(function() {
      // 获取图书列表数据
      function getBookList() {
        $.get('http://www.liulongbin.top:3006/api/getbooks', function(res) {
          if(res.status !== 200){
            return alert('获取数据失败!');
          }
          
          var rows = []
          $.each(res.data, function(i, item) {
            rows.push('<tr><td>'+item.id+'</td><td>'+item.bookname+'</td><td>'+item.author+'</td><td>'+item.publisher+'</td><td><a href="javascript:;" class="del" data-id="'+item.id+'">删除</a></td></tr>');
            //ef="javascript:;",其中javascript:是伪协议,它可以让我们通过一个链接来调用javascript函数.而采用这个方式 javascript: ; 可以实现A标签的点击事件运行时,如果页面内容很多,有滚动条时,页面不会乱跳,用户体验更好。
          })
          $('#tb').empty().append(rows.join(''))
          //join() 方法通过连接数组中的所有元素创建并返回一个新字符串,用逗号或指定的分隔符字符串分隔。如果数组只有一项,则将不使用分隔符返回该项。
        })
      }
      getBookList();  // 调用获取图书列表

      // 后期通过DOM操作添加上去的元素无法动态绑定
      // $('.del')on('click',function() {
      //   console.log('ok');
      // })

      // 通过代理的方式为动态添加的元素绑定点击事件,tbody 代理 del 响应了 click
      $('tbody').on('click', '.del', function () {
        // '.del' 记得加 .
        var id = $(this).attr('data-id');
        $.get('http://www.liulongbin.top:3006/api/delbook', { id: id }, function (res) {
          if (res.status != 200) {
            return alert('删除图书失败!');
          }
          getBookList();
        });
      });
    })

    $('#btnAdd').on('click', function() {
      // val() 获取文本框的值, trim() 去除字符串两端的空格。防止用户输入一串空格
      var bookname = $('#iptBookname').val().trim();
      var author = $('#iptAuthor').val().trim();
      var publisher = $('#iptPublisher').val().trim();
      if(bookname.length <= 0 || author.length <= 0 || publisher.length <= 0) {
        return alert('请填写完整的图书信息!');
      }

      $.post('http://www.liulongbin.top:3006/api/addbook',
      { bookname: bookname, author:author, publisher:publisher},
        function (res) {
          if (res.status !== 201) {
            return alert('添加图书失败!');
          }
          getBookList();
          $('#iptBookname').val('');
          $('#iptAuthor').val('');
          $('#iptPublisher').val('');
          //将文本框中的值设置为空
        })
    })
  </script>
</body>
</html>

2. form 表单的基本使用

2.1 什么是表单

        表单主要负责数据采集功能。

2.2 表单的组成部分

(1)表单标签

(2)表单域

(3)表单按钮

2.3 <form> 标签的属性

        属性用来规定如何把采集到的数据发送到服务器的

        

 2.3.1 action

        action 属性用来规定当提交表单时,向何处发送表单数据

        action 的值应为专门负责接收表单提交的数据的 URL 地址

        当 <form> 表单在未指定 action 属性值的情况下,action 的默认值为当前页面的 URL 地址

        注意:当提交表单后,页面会立刻跳转到 action 属性指定的 URL 地址

2.3.2 target

        target 属性用来规定在何处打开 action URL

        target 的可选值有5个,默认情况下为 _self,表示在相同的框架下打开 action URL

        

2.3.3 method 属性

        method 属性用来规定以何种 方式把表单数据提交到 action URL

        method 有两个可选值,get 和 post, 默认为 get, 表示以 URL 地址的形式,把表单数据提交到 action URL

        get 适合用来提交少量、简单的数据,post 适合用来提交大量的、复杂的或文件上传的数据(post 更为安全)

        登录、注册、添加数据等表单操作都需要使用 post 方式来提交表单数据

        get 方式: 

         post 方式:

2.3.4  enctype

         enctype 属性用来规定在发送表单之前如何对数据进行编码

        

         如果表单的提交涉及文件上传,必须设置为 multipart/form-urlencoded,不涉及则设置为 application/x-www-form-urlencoded 即可

例子:

<body>
  <form action="/login" target="_blank" method="post">
    <input type="text" name="email_or_mobile" />
    <input type="password" name="password" />
    <button type="submit">提交</button>
  </form>
</body>

2.4 表单的同步提交及缺点

2.4.1 表单的同步提交

        通过点击 submit 按钮,触发表单提交的操作,从而使页面跳转到 actio URL 的行为

2.4.2 缺点

(1)整个页面跳转到 action URL 所指的地址,用户体验差

(2)同步提交后,页面之前的状态和数据会丢失

2.4.3 解决

        表单只复杂采集数据, Ajax 负责将数据提交到服务器

3. 通过 Ajax 提交表单数据

3.1 监听表单提交事件

    $(function() {
      // 第一种
      $('#f1').submit(function() {
        alert('ok');
      })

      // 第二种
      $("#f1").on('submit', function() {
        alert('success');
      })
    })

3.2 阻止表单默认提交行为

        监听到表单的提交事件后,页面仍会跳转,当监听到表单的提交事件后,可调用事件对象的 event.preventDafault() 函数,来阻止表单的提交和页面的跳转

    $(function() {
      // 第一种
      $('#f1').submit(function(e) {
        alert('ok');
        e.preventDefault();
      })

      // 第二种
      $("#f1").on('submit', function(e) {
        alert('success');
        e.preventDefault();
      })
    })

3.3 快速获取表单数据

3.3.1 serialize() 函数

        可以一次性获取到表单中的所有数据

        注意:在使用 serialize() 函数时,必须为每个表单元素添加 name 属性

$(selector).serialize()
    $(function() {
      // 第一种
      $('#f1').submit(function(e) {
        alert('ok');
        e.preventDefault();
        var data = $(this).serialize()
        console.log(data);
      })

例子:评论列表

代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./lib/bootstrap.css"/>
  <script src="./lib/jquery.js"></script>
  <script src="./js/cmt.js"></script>
</head>
<body style="padding: 15px;">
  <!-- 评论面板 --> 
  <!-- bs3-panel:primary -->
  
  <div class="panel panel-primary">
      <div class="panel-heading">
        <h3 class="panel-title">发表评论</h3>
      </div>
      <form class="panel-body" id="formAddCmt">
        <div>评论人:</div>
        <input type="text" class="form-control" name="username">
        <div>评论内容:</div>
        <textarea class="form-control" name="content"></textarea>
        <button type="submit" class="btn btn-primary">发表评论</button>
      </form>
  </div>
  
  <!-- 评论列表 -->
  <!-- bs3-list-group:badges -->
  
  <ul class="list-group" id="cmt-list">
    <li class="list-group-item">
      <span class="badge" style="background-color: rgb(147, 168, 238);">评论人:</span>
      <span class="badge" style="background-color: pink;">评论时间:</span>
      <!-- 顺序不同是因为浮动 -->
      Item 1
    </li>
  </ul>
  
</body>
</html>
function getCommentList() {
  $.ajax({
    method: 'GET',
    url: 'http://www.liulongbin.top:3006/api/cmtlist',
    success: function(res){
      if(res.status != 200) return alert('获取评论列表失败!');
      var rows = [];
      $.each(res.data, function(i, item) {
        var str = '<li class="list-group-item"><span class="badge" style="background-color: rgb(147, 168, 238);">评论人:'+item.username+'</span><span class="badge" style="background-color: pink;">评论时间:'+item.time+'</span>'+item.content+'</li>'
        rows.push(str);
      })
      $('#cmt-list').empty().append(rows.join(''))
    }
  })
}

getCommentList();

$(function() {
  $('#formAddCmt').submit(function(e) {
    e.preventDefault()
    var data = $(this).serialize()
    $.post("http://www.liulongbin.top:3006/api/addcmt", data, function(res) {
      if(res.status != 201){
        return alert('发表评论失败!')
      }
      getCommentList();
      //清空表单,获取整个表单,将jQuery对象转成DOM对象,再调用reset
      $('#formAddCmt')[0].reset();
    });
  })
})

4. XMLHttpRequest 的基本使用

4.1 概念

        XMLHttpRequest(简称 xhr)是浏览器提供的 JavaScript 对象,可通过它请求服务器上的数据资源。jQuery 中的 Ajax 函数,就是基于 xhr 对象封装出来的。

4.2 使用 xhr 发起 GET 请求

        步骤:

(1)创建 xhr 对象

(2)调用 xhr.open() 函数创建请求

(3)调用 xhr.send() 函数发起请求

(4)监听 xhr.onreadystatechange 事件拿取服务器响应的数据

    // 1. 创建 xhr 对象
    var xhr = new XMLHttpRequest();
    // 2.调用 open 函数
    xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks');
    // 3.调用 send 函数
    xhr.send();
    // 4. 监听 onreadystatechange 事件
    xhr.onreadystatechange = function() {
      // 下面这一行为固定写法
      if(xhr.readyState === 4 && xhr.status === 200){
        // 获取服务器响应的数据
        console.log(xhr.responseText);
      }
    }

4.3 了解 xhr 对象的 readyState 属性

        xhr 对象的 readyState 属性,表示当前 Ajax 对象请求所处的状态,每个 Ajax 请求必然处于以下状态中的一种

4.4 使用 xhr 发起带参数的 GET 请求

         使用 xhr 发起带参数的 GET 请求,只需在调用 xhr.open 期间,为 URL 地址指定参数即可

        参数通过键值对的形式进行指定,多个参数则用 & 拼接

xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks?id=1');

        在 URL 地址后面拼接的参数,叫做查询字符串

    // 1. 创建 xhr 对象
    var xhr = new XMLHttpRequest();
    // 2.调用 open 函数
    xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks?id=1');
    // 3.调用 send 函数
    xhr.send();
    // 4. 监听 onreadystatechange 事件
    xhr.onreadystatechange = function() {
      // 下面这一行为固定写法
      if(xhr.readyState === 4 && xhr.status === 200){
        // 获取服务器响应的数据
        console.log(xhr.responseText);
      }
    }

 4.5 查询字符串

4.5.1 概念

        定义:查询字符串(URL 参数)是指在 URL 的末尾加上用于向服务器发送信息的字符串(变量)

        格式:将 ? 放在 URL 的末尾,再加上 参数 = 值 ,若有多个参数,使用 & 符号进行分隔。这样可将想要发送给服务器的数据添加到 URL 中

xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=西游记');

4.5.2 GET 请求携带参数的本质

        $.ajax(), $.get() 或者使用 xhr 对象,本质上都是将参数以查询字符串的形式追加到 URL 地址的后面,再发送到服务器的

4.6 URL 编码与解码

4.6.1 概念

        URL 地址中只允许出现英文相关的字母、标点符号、数字,若 URL 包含中文,则对其进行编码(转义)

        URL 编码的原则:使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示不安全的字符

4.6.2 如何对 URL 进行编码与解码

        浏览器提供了 URL 编码与解码的 API,为:

        encodeURI():编码的函数

        decodeURI():解码的函数

    var str = '你好';
    var str2 = encodeURI(str);
    console.log(str2);
    // %E4%BD%A0%E5%A5%BD
    var str3 = decodeURI(str2);
    console.log(str3);
    // 你好

4.7 使用 xhr 发起 POST 请求

        步骤:

(1)创建 xhr 对象

(2)调用 xhr.open() 函数

(3)设置 Content-Type 属性(固定写法)

(4)调用 xhr.send() 函数,同时指定要发送的数据

 (5)监听 xhr.onreadystatechange 事件拿取服务器响应的数据

    // 1. 创建 xhr 对象
    var xhr = new XMLHttpRequest();
    // 2.调用 open 函数
    xhr.open('POST', 'http://www.liulongbin.top:3006/api/addbook');
    // 3.设置 Content-Type 属性(固定写法)
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
    // 4.调用 send 函数,同时将指定的数据以查询字符串的形式,提交给服务器
    xhr.send('bookname=水浒传&author=施耐庵&publisher=上海图书出版社');
    // 4. 监听 onreadystatechange 事件
    xhr.onreadystatechange = function() {
      // 下面这一行为固定写法
      if(xhr.readyState === 4 && xhr.status === 200){
        // 获取服务器响应的数据
        console.log(xhr.responseText);
      }
    }

 5. 数据交换格式

5.1 概念

        数据交换格式:服务器端与客户端之间进行数据传输与交换的格式

5.2 XML

        XML 是可扩展标记语言,被设计用来传输和存储数据,是数据的载体

5.3 JSON

5.3.1 概念

        JSON,即“JavaScript 对象表达法”,是 JavaScript 对象和数组的字符串表示法,它使用文本表示一个 JS 对象或者数组的信息,JSON的本质是字符串

        JSON 是一种轻量级的文本交换格式,专门用于存储和传输数据

5.3.2 JSON 的两种结构

        对象结构是在 JSON 中表示为 { } 括起来的内容,数据结构为 { key: value, key: value, ... } 的键值对结构。key 必须为使用双引号包裹的字符串,value 的数据类型可为数字、字符串、布尔值、null、数组、对象 6种类型

        数组结构:数组结构在 JSON 中表示为 [ ] 括起来的内容。数据结构为[ "java", "javasgript",30, true ... ] 。数组中数据的类型可为数字、字符串、布尔值、null、数组、对象 6 种类型

5.3.3 JSON 语法注意事项

(1) 属性名必须使用双引号包裹

(2)字符串类型的值必须使用双引号包裹

(3)JSON 中不允许使用单引号表示字符串

(4)JSON 中不能写注释

(5)JSON 的最外层必须是对象或者数组格式

(6)不能使用 undefined 或函数作为 JSON 的值

5.3.4 JSON 和 JS 对象的关系

        JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串

    // 这是对象
    var obj = {a: 'Hello', b: 'World'}
    // 这是 JSON 字符串
    var json = '{"a": "Hello", "b": "World"}'

5.3.5 JSON  和 JS 对象的互转

        使用 JSON.parse() 方法可将 JSON 字符串转换为 JS 对象( xhr.responseText 为 JSON 字符串时,可转换为 JS 对象)

    var jsonStr = '{"a": "Hello", "b": "World"}';
    var obj = JSON.parse(jsonStr);
    console.log(obj);
    // {a: 'Hello', b: 'World'}

        使用 JSON.stringify() 方法可将 JS 对象转换为 JSON 字符串

    var jsStr = { a: 'Hello', b: 'World', c: false};
    var obj = JSON.stringify(jsStr);
    console.log(obj);
    // {"a":"Hello","b":"World","c":false}

5.3.6 序列化和反序列化

        序列化:把数据对象转换为字符串,例如,JSON.stringify()

        反序列化:把字符串转换为数据对象,例如,JSON.parse()

6. XMLHttpRequest Level2 

6.1 新特性

(1)可设置 HTTP 请求的时限

(2)可使用 FromData 对象管理表单数据

(3)可上传文件

(4)可获得数据传输的进度信息

6.2 设置 HTTP 请求时限

        timeout 属性可设置请求时限,单位为毫秒,超过设置值则自动停止 HTTP 请求

xhr.timeout = 3000;

        配套的有 timeout 事件,用来指定回调函数

    var xhr = new XMLHttpRequest();
    // 设置超时时间
    xhr.timeout = 1;
    // 设置超时以后的处理函数
    xhr.ontimeout = function() {
      console.log('请求超时了!');
    }
    xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks');
    xhr.send();
    xhr.onreadystatechange = function() {
      if(xhr.readyState === 4 && xhr.status === 200){
        console.log(xhr.responseText);
      }
    }

6.3 FromData 对象管理表单数据

    // 1.创建 FromData 实例
    var fd = new FormData();
    // 2. 调用 append 函数,向 fd 中追加数据
    fd.append('uname','zs');
    fd.append('upwd','123');
    // 3. 创建 xhr 对象
    var xhr = new XMLHttpRequest();
    // 4. 指定请求类型与 URL 地址
    xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata');
    // 5. 直接提交 FromData 对象,这与提交网页表单的效果一致
    xhr.send(fd);
    // 6. 监听 onreadystatechange 事件
    xhr.onreadystatechange = function() {
      if(xhr.readyState === 4 &&xhr.status === 200) {
        console.log(JSON.parse(xhr.responseText))
      }
    }

         FromData 对象也可以用来获取网页表单的值

    // 1. 通过 DOM 操作,获取 form 表单元素
    var form = document.querySelector('#form1');

    form.addEventListener('submit', function(e) {
      // 阻止表单的默认提交行为
      e.preventDefault()

      // 创建 FromData,快速获取 form 表单中的数据 
      var fd = new FormData(form);

      var xhr = new XMLHttpRequest();
      xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
      xhr.send(fd)
      xhr.onreadystatechange = function() {
        if(xhr.readyState === 4 && xhr.status === 200){
          console.log(JSON.parse(xhr.responseText));
        }
      }
    })

 6.4 上传文件

        步骤:

(1)定义 UI 结构

(2)验证是否选择了文件

(3)向 FormData 中追加文件

(4)使用 xhr 发起上传文件的请求

(5)监听 onreadystatechange 事件

<body>
  <!-- 文件选择框 -->
  <input type="file" id="file1" />
  <!-- 上传按钮 -->
  <button id="btnUpload">上传文件</button>
  <br />
  <!-- 用来显示上传成功后的图片 -->
  <img src="" alt="" id="img" width="300">

  <script>
    // 1. 获取文件上传按钮
    var btnUpload = document.querySelector('#btnUpload');
    // 2. 为按钮绑定单击事件处理事件
    btnUpload.addEventListener('click', function() {
      // 3. 获取用户选择的文件列表
      var files = document.querySelector('#file1').files
      if(files.length <= 0) {
        return alert('请选择要上传的文件!');
      }
      var fd = new FormData();
      // 将用户选择的文件添加到 FormData 中
      fd.append('avatar', files[0]);

      var xhr = new XMLHttpRequest();
      xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar');
      xhr.send(fd);
      
      xhr.onreadystatechange = function() {
        if(xhr.readyState === 4 && xhr.status === 200) {
          var data = JSON.parse(xhr.responseText);
          // 这里的等于200是由接口文档决定的,上面的是固定写法
          if(data.status === 200) {
            // 上传成功
            document.querySelector('#img').src = 'http://www.liulongbin.top:3006' + data.url;
          }
          else {
            console.log('图片上传失败!' + data.message);
          }
        }
      }
    })
  </script>
</body>

6.5 显示文件上传的速度

        新版本的 XMLHttpRequest 对象中,可通过监听 xhr.upload.onprogress 事件,来获取文件的上传速度

      var xhr = new XMLHttpRequest();

      // 监听文件上传的进度
      xhr.upload.onprogress = function(e) {
        // e.lengthComputable 是一个布尔值,表示当前上传的资源是否具有可计算的长度
        if(e.lengthComputable) {
          // 计算上传的进度,e.loaded 为
          var procentComplete = Math.ceil((e.loaded / e.total) * 100);
          console.log(procentComplete);
        }
      }

        显示进度条

  <!-- bootstrap 的进度条 -->
  <div class="progress" style="width: 500px; margin: 15px 10px;">
    <div class="progress-bar progress-bar-striped progress-bar-animated" 
      aria-valuemin="0" aria-valuemax="100" style="width: 0%" id="precent">0</div>
      // 监听文件上传的进度
      xhr.upload.onprogress = function(e) {
        // e.lengthComputable 是一个布尔值,表示当前上传的资源是否具有可计算的长度
        if(e.lengthComputable) {
          // 计算上传的进度,e.loaded 为
          var procentComplete = Math.ceil((e.loaded / e.total) * 100);
          console.log(procentComplete);
          // 动态设置进度条
          $('#precent').attr('style', 'width: ' + procentComplete + '%;').html(procentComplete + '%')
        }
      }

        当上传完成时,进度条样式变化

      xhr.upload.onload = function() {
        $('#precent').removeClass().addClass('progress-bar progress-bar-success')
      }

7.  jQuery 高级用法

7.1 jQuery 实现文件上传

<body>
  <input type="file" id="file1">
  <button id="btnUpload">上传文件</button>

  <script>
    $(function() {
      $('#btnUpload').on('click', function() {
        // 将 jQuery 对象转换为 DOM 对象,并获取选中的文件列表
        var files = $('#file1')[0].files
        if(files.length <= 0) {
          return alert('请选择文件后再上传!');
        }
        
        var fd = new FormData();
        fd.append('avatar', files[0])

        // 发起 jQuery 的 Ajax 请求,上传文件
        // 必须调用 $.ajax, 不能是 $.post
        $.ajax({
          method:'POST',
          url:'http://www.liulongbin.top:3006/api/upload/avatar',
          data:fd,
          // 不修改 Content-Type 属性,使用 FromData 默认的 Content-Type 值
          contentType:false,
          // 不对 FormData 中的数据进行 url 编码,而是将 FormData 数据原样发到服务器
          processData:false,
          // 以上两句必须要写,且为固定写法
          success: function(res) {
            console.log(res);
          }
        })
      })
    })
  </script>
</body>

7.2  jQuery 实现 loading 效果

        Ajax 请求开始时,执行 ajaxStart 函数,可以在 ajaxStart 的 callback 中显示 loading 效果

        Ajax 请求结束时,执行 ajaxStop 函数,可以在 ajaxStop 的 callback 中隐藏 loading 效果

        注意:$(document).ajaxStart 函数会监听到当前文档内所有的 Ajax 请求

  <img src="./images/loading.gif" alt="" style="display: none;" id="loading" />
      // 监听到 ajaxStart 再展示
      $(document).ajaxStart(function() {
        $('#loading').show;
      })

      $(document).ajaxStop(function() {
        $('#loading').hide;
      })

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值