XMLHttpRequest 与 Ajax

XMLHttpRequest

XMLHttpRequest(简称 xhr)是浏览器提供的 Javascript 对象,通过它,可以请求服务器上的数据资源。

在这里插入图片描述

Ajax

简介

1.Ajax术语最早产生于2015年。

2.Ajax表示Asynchronous Javascript and XML(异步 JS XML)

3.是浏览器提供的一套方法,可以实现页面无刷新更新数据,提高用户体验

应用场景

(1)页面上拉加载数据

(2)列表数据无刷新分页

(3)表单项离开焦点数据验证

(4)搜索框提示文字下拉列表

传统网站存在问题

(1)网速慢情况下,页面加载时间长,用户只能等待。

(2)表单提交后,如果一项不合格,需要重新填写。

运行环境

Ajax技术需要运行在网站环境中才能生效,不能直接右键运行

Ajax运行原理以及实现

在这里插入图片描述

Ajax和XMLHttpRequest

我们通常将Ajax等同于XMLHttpRequest
但细究起来它们两个是属于不同维度的2个概念。
ajax是一种技术方案,但并不是一种新技术。
它依赖的是现有的CSS/HTML/Javascript
而其中最核心的依赖是浏览器提供的XMLHttpRequest对象
是这个对象使得浏览器可以发出HTTP请求与接收HTTP响应。

一句话来总结两者的关系:使用XMLHttpRequest对象来发送一个Ajax请求。

Ajax实现步骤:

1)创建Ajax对象 var xhr = new XMLHttpRequst();
2)告诉Ajax请求地址和方式 xhr.open('get','http://www.example.com')
3)发送请求 xhr.send();
4)获取服务器给与客户端的想要数据 
// 1. 创建 XHR 对象
var  xhr  =  new  XMLHttpRequest()
    // 2. 调用 open 函数,指定 请求方式 与 URL地址
xhr.open('GET',  'http://www.liulongbin.top:3006/api/getbooks')
    // 3. 调用 send 函数,发起 Ajax 请求
xhr.send()
    // 4. 监听 onreadystatechange 事件
xhr.onreadystatechange  =   function()  {
    
    
    // 4.1 监听 xhr 对象的请求状态 readyState ;与服务器响应的状态 status
    if  (xhr.readyState  ===  4  &&  xhr.status  ===  200)  {
    
    
        // 4.2 打印服务器响应回来的数据
        console.log(xhr.responseText)
    }
}

xhr对象的readyState属性

XMLHttpRequest 对象的 readyState 属性,用来表示当前 Ajax 请求所处的状态。

每个 Ajax 请求必然处于以下状态中的一个:

在这里插入图片描述

index.html文件

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<script type="text/javascript">
		// 1.创建ajax对象
		var xhr = new XMLHttpRequest();
		// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
		// 1)请求方式 2)请求地址
		xhr.open('get', 'http://localhost:3000/first');
		// 3.发送请求
		xhr.send();
		// 4.获取服务器端响应到客户端的数据
		xhr.onload = function (){
    
    
			console.log(xhr.responseText)
		}
	</script>
</body>
</html>

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

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

// ...省略不必要的代码
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks?id=1')
// ...省略不必要的代码

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

什么是查询字符串

定义:
查询字符串(URL 参数)是指在 URL 的末尾加上用于向服务器发送信息的字符串(变量)。
格式:
将英文的 ? 放在URL 的末尾,然后再加上 参数=值 ,
想加上多个参数的话,使用 & 符号进行分隔。
以这个形式,可以将想要发送给服务器的数据添加到 URL 中。
// 不带参数的 URL 地址
http://www.liulongbin.top:3006/api/getbooks
// 带一个参数的 URL 地址
http://www.liulongbin.top:3006/api/getbooks?id=1
// 带两个参数的 URL 地址
http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=西游记

GET请求携带参数的本质

无论使用 $.ajax(),还是使用 $.get(),又或者直接使用 xhr 对象发起 GET 请求,当需要携带参数的时候

本质上,都是直接将参数以查询字符串的形式,追加到 URL 地址的后面,发送到服务器的。

$.get('url', {
    
     name: 'zs', age: 20 }, function() {
    
    })
    // 等价于
$.get('url?name=zs&age=20', function() {
    
    })

$.ajax({
    
     method: 'GET', url: 'url', data: {
    
     name: 'zs', age: 20 }, success: function() {
    
    } })
    // 等价于
$.ajax({
    
     method: 'GET', url: 'url?name=zs&age=20', success: function() {
    
    } })

URL编码与解码

什么是URL编码

URL 地址中,只允许出现英文相关的字母、标点符号、数字,因此,在 URL 地址中不允许出现中文字符。

如果 URL 中需要包含中文这样的字符,则必须对中文字符进行编码(转义)。

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

URL编码原则的通俗理解:使用英文字符去表示非英文字符

http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=西游记
// 经过 URL 编码之后,URL地址变成了如下格式:
http://www.liulongbin.top:3006/api/getbooks?id=1&bookname=%E8%A5%BF%E6%B8%B8%E8%AE%B0

如何对URL进行编码与解码

浏览器提供了 URL 编码与解码的 API,分别是:
encodeURI() 编码的函数
decodeURI() 解码的函数

encodeURI('程序员')
    // 输出字符串  %E7%A8%8B%E5%BA%8F%E5%91%98
decodeURI('%E7%A8%8B%E5%BA%8F%E5%91%98')
    // 输出字符串  程序员

URL编码的注意事项

由于浏览器会自动对 URL 地址进行编码操作,因此,大多数情况下,程序员不需要关心 URL 地址的编码与解码操作。

更多关于 URL 编码的知识,请参考如下博客:
https://blog.csdn.net/Lxd_0111/article/details/78028889

使用xhr发起POST请求

创建 xhr 对象
调用 xhr.open() 函数
设置 Content-Type 属性(固定写法)
调用 xhr.send() 函数,同时指定要发送的数据
监听 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=天津图书出版社')
            // 5. 监听 onreadystatechange 事件
        xhr.onreadystatechange  =   function()  {
    
    
            if  (xhr.readyState  ===  4  &&  xhr.status  ===  200)  {
    
    
                console.log(xhr.responseText)
            }
        }

请求参数的格式

application/x-www-form-urlencoded
name=zhangsan&age=20&sex=
application/json
{
    
    name: 'zhangsan', age: '20', sex: '男'}

在请求头中指定 Content-Type 属性的值是 application/json,告诉服务器端当前请求参数的格式是 json。

 JSON.stringify() 将json对象转换为json字符串

注:get 请求是不能提交 json 对象数据格式的,传统网站的表单提交也是不支持 json 对象数据格式的。

数据交换格式

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

前端领域,经常提及的两种数据交换格式分别是 XML 和 JSON。

其中 XML 用的非常少,所以,重点要学习的数据交换格式就是 JSON。
在这里插入图片描述

XML

XML 的英文全称是 EXtensible Markup Language,即可扩展标记语言。因此,XML 和 HTML 类似,也是一种标记语言。
在这里插入图片描述

XML和HTML的区别

XML 和 HTML 虽然都是标记语言,但是,它们两者之间没有任何的关系。

HTML 被设计用来描述网页上的内容,是网页内容的载体

XML 被设计用来传输和存储数据,是数据的载体

XML的缺点

ML 格式臃肿,和数据无关的代码多,体积大,传输效率低

在 Javascript 中解析 XML 比较麻烦

JSON

概念:JSON 的英文全称是 JavaScript Object Notation,即“JavaScript 对象表示法”。

简单来讲,JSON 就是 Javascript 对象和数组的字符串表示法,它使用文本表示一个 JS 对象或数组的信息,因此,JSON 的本质是字符串。

作用:JSON 是一种轻量级的文本数据交换格式,在作用上类似于 XML,专门用于存储和传输数据,但是 JSON 比 XML 更小、更快、更易解析。

现状:JSON 是在 2001 年开始被推广和使用的数据格式,到现今为止,JSON 已经成为了主流的数据交换格式。

JSON的两种结构

JSON 就是用字符串来表示 Javascript 的对象和数组。

所以,JSON 中包含  对象  和  数组  两种结构

通过这两种结构的相互嵌套,可以表示各种复杂的数据结构。
对象结构

对象结构在 JSON 中表示为 { } 括起来的内容。

数据结构为 { key: value, key: value, … } 的键值对结构。

其中,key 必须是使用英文的双引号包裹的字符串,value 的数据类型可以是数字、字符串、布尔值、null、数组、对象6种类型。

{
    
    
    "name": "zs",
    "age": 20,
    "gender": "男",
    "address": null,
    "hobby": ["吃饭", "睡觉", "打豆豆"]
}
数组结构

数组结构在 JSON 中表示为 [ ] 括起来的内容。

数据结构为 [ “java”, “javascript”, 30, true … ] 。

数组中数据的类型可以是数字、字符串、布尔值、null、数组、对象6种类型。

[ "java", "python", "php" ]
[ 100, 200, 300.5 ]
[ true, false, null ]
[ {
    
     "name": "zs", "age": 20}, {
    
     "name": "ls", "age": 30} ]
[ [ "苹果", "榴莲", "椰子" ], [ 4, 50, 5 ] ]
JSON语法注意事项
属性名必须使用双引号包裹

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

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

JSON 中不能写注释

JSON 的最外层必须是对象或数组格式

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

JSON 的作用:在计算机与网络之间存储和传输数据。
JSON 的本质:用字符串来表示 Javascript 对象数据或数组数据
JSON和JS对象的关系

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

//这是一个对象
var obj = {
    
    a: 'Hello', b: 'World'}

//这是一个 JSON 字符串,本质是一个字符串
var json = '{"a": "Hello", "b": "World"}' 
JSON和JS对象的互转

要实现从 JSON 字符串转换为 JS 对象,使用 JSON.parse() 方法:

var obj = JSON.parse('{"a": "Hello", "b": "World"}')
//结果是 {a: 'Hello', b: 'World'}

要实现从 JS 对象转换为 JSON 字符串,使用 JSON.stringify() 方法:

var json = JSON.stringify({
    
    a: 'Hello', b: 'World'})
//结果是 '{"a": "Hello", "b": "World"}'
序列化和反序列化
把数据对象转换为字符串的过程,叫做序列化,
例如:调用 JSON.stringify() 函数的操作,叫做 JSON 序列化。

把字符串转换为数据对象的过程,叫做反序列化,
例如:调用 JSON.parse() 函数的操作,叫做 JSON 反序列化。

Ajax处理服务器端返回的JSON数据

1.在真实的项目中,服务器端大多数情况下会以 JSON 对象作为响应数据的格式。当客户端拿到响应数据时,要将 JSON 数据和 HTML 字符串进行拼接,然后将拼接的结果展示在页面中。

2.在 http 请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输。

3.JSON.parse() // 将 json 字符串转换为json对象

			// 将JSON字符串转换为JSON对象
			var responseText = JSON.parse(xhr.responseText);
			// 测试:在控制台输出处理结果
			console.log(responseText)
			// 将数据和html字符串进行拼接
			var str = '<h2>'+ responseText.name +'</h2>';
			// 将拼接的结果追加到页面中
			document.body.innerHTML = str;

示例:

		// 1.创建ajax对象
		var xhr = new XMLHttpRequest();
		// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
		// 1)请求方式 2)请求地址
		xhr.open('post', 'http://localhost:3000/json');
		// 通过请求头告诉服务器端客户端向服务器端传递的请求参数的格式是什么
		xhr.setRequestHeader('Content-Type', 'application/json');
		// JSON.stringify() 将json对象转换为json字符串
		// 3.发送请求
		xhr.send(JSON.stringify({
    
    name: 'lisi', age:50}));
		// 4.获取服务器端响应到客户端的数据
		xhr.onload = function (){
    
    
			console.log(xhr.responseText)

Ajax获取服务端响应

1.onload事件

2.onreadystatechange事件

在这里插入图片描述

Ajax错误处理

1.网络畅通,服务器端能接收到请求,服务器端返回的结果不是预期结果。
可以判断服务器端返回的状态码,分别进行处理。
xhr.status 获取http状态码

			// 1.创建ajax对象
			var xhr = new XMLHttpRequest();
			// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
			// 1)请求方式 2)请求地址
			xhr.open('get', 'http://localhost:3000/error');
			// 3.发送请求
			xhr.send();
			// 4.获取服务器端响应到客户端的数据
			xhr.onload = function (){
    
    
				// xhr.status 获取http状态码
				console.log(xhr.responseText);

				if (xhr.status == 400) {
    
    
					alert('请求出错')
				}
		
app.get('/error', (req, res) => {
    
    
	//console.log(abc);
	res.status(400).send('not ok');
});

2.网络畅通,服务器端没有接收到请求,返回404状态码。
检查请求地址是否错误。

3.网络畅通,服务器端能接收到请求,服务器端返回500状态码。
服务器端错误,找后端程序员进行沟通。

4.网络中断,请求无法发送到服务器端。
会触发xhr对象下面的onerror事件,在onerror事件处理函数中对错误进行处理。

Ajax状态码: 表示Ajax请求的过程状态 ajax对象返回的

Http状态码: 表示请求的处理结果 是服务器端返回的

低版本 IE 浏览器的缓存问题

问题:在低版本的 IE 浏览器中,Ajax 请求有严重的缓存问题,即在请求地址不发生变化的情况下,只有第一次请求会真正发送到服务器端

后续的请求都会从浏览器的缓存中获取结果。即使服务器端的数据更新了,客户端依然拿到的是缓存中的旧数据。

解决方案:在请求地址的后面加请求参数,保证每一次请求中的请求参数的值不相同。

xhr.open('get', 'http://www.example.com?t=' + Math.random());

Ajax异步编程

同步

一个人同一时间只能做一件事情,只有一件事情做完,才能做另外一件事情。

落实到代码中,就是上一行代码执行完成后,才能执行下一行代码,即代码逐行执行。

例子:服务员给1号客人点菜,点好以后等待厨师做菜,做好以后端给1号客人,在为2号客人点菜。

console.log('before'); 
 console.log('after');

异步

一个人一件事情做了一半,转而去做其他事情,当其他事情做完以后,再回过头来继续做之前未完成的事情。

落实到代码上,就是异步代码虽然需要花费时间去执行,但程序不会等待异步代码执行完成后再继续执行后续代码,而是直接执行后续代码,当后续代码执行完成后再回头看异步代码是否返回结果,如果已有返回结果,再调用事先准备好的回调函数处理异步代码执行的结果。

例子:服务员给1号客人点菜,点完后交给厨师做菜,期间为2号客人点菜,菜做好以后再给1号客人端上来,提高了效率。

console.log('before');
 setTimeout(
    () => {
    
     console.log('last');
 }, 2000);
 console.log('after');

示例:

		// 1.创建ajax对象
		var xhr = new XMLHttpRequest();
		// 2.告诉Ajax对象要向哪发送请求,以什么方式发送请求
		// 1)请求方式 2)请求地址
		xhr.open('get', 'http://localhost:3000/first', false);
		// 3.发送请求
		xhr.send();
		// 4.获取服务器端响应到客户端的数据
		xhr.onreadystatechange = function (){
    
    
			if (xhr.readyState == 4) {
    
    
				console.log('2')
				console.log(xhr.responseText)
			}
			
		}

		console.log('1');

在这里插入图片描述

Ajax封装

问题:发送一次请求代码过多,发送多次请求代码冗余且重复

解决方案:将请求代码封装到函数中,发请求时调用函数即可。

猜你喜欢

转载自blog.csdn.net/Ulrica_Amaris/article/details/108617810