Ajax第三天

150 阅读6分钟

1.XMLHttpRequest

是浏览器内置的一个构造函数
作用:基于 new 出来的 XMLHttpRequest 实例对象,可以发起 Ajax 的请求。
axios 中的 axios.get()、axios.post()、axios() 方法,都是基于 XMLHttpRequest(简称:XHR) 封装出来的!
使用 XMLHttpRequest 发起 GET 请求

image.png

image.png

发起 GET 请求时携带查询参数

image.png

 <script>
//创建XHR对象
const xhr = new XMLHttpRequest()
//设置请求和资源路径
xhr.open('GET', 'http://www.liulongbin.top:3009/api/getbooks?id=3&bookname=三国演义')
//发送
xhr.send()
//接收响应
xhr.addEventListener('load', function () {
  //返回的数据是JSON字符串
  console.log(xhr.response); //then(({data:res})=>{})
  //把JSON字符串转换为对象
  console.log(JSON.parse(xhr.response));
})
</script>

image.png

XMLHttpRequest 发起 POST 请求,并携带查询参数

image.png

使用 XMLHttpRequest 发起 POST 请求,并携带请求体数据

image.png

<script>
//创建XHR对象
const xhr = new XMLHttpRequest()
//设置请求和资源路径
xhr.open('POST', 'http://www.liulongbin.top:3009/api/addbook')
//发送
//方法一
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
xhr.send(`publisher=武汉人民出版社&bookname=体育&author=刘慈欣`)
//方法二
// xhr.setRequestHeader('content-type', 'application/json')
// xhr.send(`{"bookname":"前端","author":"大明","publisher":"武汉"}`)
//接收响应
xhr.addEventListener('load', function () {
  //把JSON字符串转换为对象
  console.log(JSON.parse(xhr.response));
})
</script>

image.png

2.数据交换格式

 数据交换格式,就是服务器端与客户端之间数据传输的格式
 

image.png

3.JSON

 JSON(全称:JavaScript Object Notation)是一种数据交换格式,它本质上是用字符串的方式来表示对象或数组类型的数据
 

image.png

4.JSON 数据

用字符串的方式来表示的对象或数组类型的数据,叫做 JSON 数据

JSON 数据的格式有两种:1.对象格式  2.数组格式

5.对象格式的 JSON 数据

 对象格式的 JSON 数据,最外层使用 {  } 进行包裹,内部的数据为 key: value 的键值对结构。其中:
  1. key 必须使用英文的双引号进行包裹
  2. value 的值只能是字符串、数字、布尔值、null、数组、对象类型(可选类型只有这 6 种)

image.png

6.数组格式的 JSON 数据
数组格式的 JSON 数据,最外层使用 [  ] 进行包裹,内部的每一项数据之间使用英文的 , 分隔。其中:
每一项的值类型只能是字符串、数字、布尔值、null、数组、对象这 6 种类型之一

image.png

7.把 JSON 数据转换为 JS 数据

调用浏览器内置的 JSON.parse() 函数,可以把 JSON 格式的字符串转换为 JS 数据

image.png

8.把 JS 数据转换为 JSON 数据

调用浏览器内置的 JSON.stringify() 函数,可以把 JS 数据转换为 JSON 格式的字符串

image.png

9.序列化和反序列化

 把真实数据转换为字符串的过程,叫做序列化
 把字符串转换为真实数据的过程,叫做反序列化
 

image.png

10.把 XMLHttpRequest 请求到的 JSON 数据反序列化为 JS 对象

在 xhr 对象的 load 事件中,通过 xhr.response 访问到的是 JSON 格式的字符串数据
可以调用 JSON.parse() 函数将 xhr.response 转化为 JS 对象。示例代码如下:

image.png

11.JSON 文件

image.png

JSON 文件的语法要求
JSON 文件中定义 JSON 格式的数据时,要遵守以下的 6 条规则:
属性名必须使用双引号包裹
字符串类型的值必须使用双引号包裹
JSON 中不允许使用单引号表示字符串
JSON 中不能写注释
JSON 的最外层必须是对象或数组格式
不能使用 undefined 或函数作为 JSON 的值

12.定义 itheima 函数的参数选项

image.png

image.png

初步定义 itheima 函数

image.png

封装Ajax案例
  // common.js   public.js    tools.js        公共的js 

// 需求: 封装一个类似 axios() 的ajax函数;
// //   注意: 以后,谁调用itheima()就要安装如下参数传递; 不传递就会报错;
// itheima({
//     method: '请求方式',
//     url: '资源路径',
//     params: '查询参数',
//     data: '请求体参数',
//     success: function (res) { // 成功的处理函数
//         console.log(res);
//     }
// });

// 定义一个函数,把对象转换为 字符串;
function objectToString(obj) {
// {a:1,b:2,c:3}  =>  'a=1&b=2&c=3'
// 思路: for...in...     
// 重点: ["a=1", "b=2", "c=3"]
const arr = [];
for (let k in obj) {
    // k代表属性,obj[k]代表值;
    // 注意: 不要乱加空格
    arr.push(`${k}=${obj[k]}`); 
}
// 转换为 'a=1&b=2&c=3'
return arr.join("&"); // 利用 for...in...
}

// 封装一个函数,发送ajax;
//    参数是一个对象; 里面有好多属性: method,url,success, params,data ;
//    如下的函数,config形参中,就有如下属性: method,url,success, params,data
function itheima(config) {
// 1.创建
const xhr = new XMLHttpRequest();
// 4.接收
xhr.addEventListener('load', function () {
    // 把JSON类型的字符串,转换为对象,方便后面操作;
    const obj = JSON.parse(xhr.response);
    // 把接收到的对象obj,交给 success() 处理
    config.success(obj);
});
// 根据请求方式的不同,给出不一样的处理结果
//     注意: toUpperCase() 转换为大写;  toLowerCase()转换为小写; 
if (config.method.toUpperCase() == 'GET') {
    // 判断,get参数是否传递;如果没有传递params属性为undefined
    if (typeof config.params == 'undefined') {
        // 2.设置 - 无参不用管参数;
        xhr.open('GET', config.url);
        // 3.发送
        xhr.send();
        // 如果传递了params属性,值为object
    } else if (typeof config.params == 'object') {
        // 2.设置 - 带有参数,就要设置路径的最后面,用?分隔;
        //   config.params是对象,我们希望把他变成 a=1&b=2&c=3
        xhr.open('GET', config.url + "?" + objectToString(config.params));
        // 3.发送
        xhr.send();
    }
} else if (config.method.toUpperCase() == 'POST') {
    // 判断post参数的类型: data属性的类型;
    if (typeof config.data == 'string') {
        // 2.设置
        xhr.open('POST', config.url);
        // 3.发送 - 设置请求头: application/x-www-form-urlencoded
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        // 把字符串类型的参数,放入send();
        xhr.send(config.data);
    } else if (typeof config.data == 'object') {
        // 2.设置
        xhr.open('POST', config.url);
        // 3.发送 - 设置请求头: application/json
        xhr.setRequestHeader('Content-Type', 'application/json');
        // 把对象类型的参数,转换为JSON类型字符串,放入send();
        xhr.send(JSON.stringify(config.data));
    }
}
}

封装方法测试

   <body>
  <script src="./common.js"></script>
  <script>
//get无参
itheima({
  method: 'get',
  url: 'http://www.liulongbin.top:3009/api/getbooks',
  success: function (res) {
    console.log(res);
  }
})
//get有参数
itheima({
  method: 'get',
  url: 'http://www.liulongbin.top:3009/api/getbooks',
  params: {
    id: 2,
    bookname: "小楼梦"
  },
  success: function (res) {
    console.log(res);
  }
})
//post请求传递字符串
itheima({
  method: 'post',
  url: 'http://www.liulongbin.top:3009/api/addbook',
  data: `bookname=三体DD一体化&author=刘慈欣&publisher=北京图书出版社`,
  success: function (res) {
    console.log(res);
  }
})
//post请求传递对象
itheima({
  method: 'post',
  url: 'http://www.liulongbin.top:3009/api/addbook',
  data: {
    bookname: "好好好好",
    author: "规范化了",
    publisher: "规范我和你"
  },
  success: function (res) {
    console.log(res);
  }
})
 </script>
 </body>

image.png

13.### 同源和跨域的概念

同源指的是两个 URL 地址具有相同的协议、主机名、端口号
同源策略(英文全称 Same origin policy)是浏览器提供的一个安全功能。浏览器的同源策略规定:不允许非同源的 URL 之间进行资源的交互。]
跨域指的是两个 URL 地址的协议、主机名、端口号三者中有一个或多个不同。出现跨域的根本原因:浏览器的同源策略不允许非同源的 URL 之间进行资源的交互
突破浏览器跨域限制有两种方案:JSONP 和 CORS

image.png

CORS 的概念
CORS 是解决跨域数据请求的终极解决方案,CORS 技术需要浏览器和服务器同时支持,二者缺一不可
CORS 的两个主要优势:支持 GET、POST、DELETE、PUT、PATCH 等这些常见的 Ajax 请求方式和只需要后端开启 CORS 功能即可,前端的代码无须做任何改动
JSONP
JSONP 是实现跨域数据请求的一种技术解决方案。它只支持 GET 请求,不支持 POSTDELETE 等其它请求。
   JSONP 不是真正的 Ajax 技术,在解决跨域问题时:
      CORS 方案用到了 XMLHttpRequest 对象,发起的是纯正的 Ajax 请求 
      JSONP 方案没有用到 XMLHttpRequest 对象,因此,JSONP 不是真正的 Ajax 技术

 结论:只要用到了 XMLHttpRequest 对象,发起的就是 Ajax 请求!

JSONP 的底层实现原理 - P1

把非同源的 JavaScript 代码请求到本地,并执行:

image.png

JSONP 的底层实现原理 - P2

如果请求回来的 JavaScript 代码只包含函数的调用,则需要程序员手动定义 show 方法

image.png

JSONP 的底层实现原理 - P3

在指定 <script> 标签的 src 属性时,可以通过查询参数中的 callback

image.png

JSONP 的底层实现原理 - P4

在指定 <script> 标签的 src 属性时,还可以通过查询参数的方式,指定要发送给服务器的数据

image.png

14.防抖

 概念:防抖(debounce)指的是:频繁触发某个操作时,只执行最后一次。 
 作用:减少逻辑执行的次数。 
 场景:搜索框只在输入完后,才执行查询的请求。 
 好处:这样可以有效减少请求的次数,节省网络资源
防抖案例
<body>
    <button>按钮</button>
 <script>
//防抖(debounce)指的是:频繁触发某个操作时,只执行最后一次
let timer; //定义变量用let不能用const
document.querySelector('button').onclick = function () {
  //取消上一次延时器
  clearTimeout(timer)
  //此处timer之前,不能加let,使用的是全局的
  timer = setTimeout(function () {
    console.log('发送Ajax...');
  }, 1000)

}
</script>
</body>

image.png

15.节流

 概念:节流(throttle)指的是:单位时间内,频繁触发同一个操作,只会触发 1 次。
 作用:减少逻辑执行的次数。 
 场景:页面新闻刷新,浏览器大小改变页面适配。 
 好处:这样可以有效减少请求的次数,节省网络资源  

节流演示案例

<body>
    <button>按钮</button>
 <script>
//节流(throttle)指的是:单位时间内,频繁触发同一个操作,只会触发 1 次
//定义一个全局变量,类似一个控制器
let flag = true
document.querySelector('button').onclick = function () {
  if (flag) {
    //进入以后,直接修改为false
    flag = false
    //利用延时器实现
    setTimeout(function () {
      console.log('发送Ajax...');
      //执行完毕修改为true
      flag = true
    }, 1000)

  }
}
 </script>
 </body>

image.png

16.ajax封装截图

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

如何转换大小写

image.png

ajax封装传递查询参数

image.png