原生AJAX

原生AJAX

1.1 AJAX 简介

AJAX 全称为Asynchronous Javascript And XML,就是异步的JS 和 XML.
通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势:无刷新的获取数据.
AJAX不是新的编程语言,而是一种将现有标准组合在一起使用的新方式.
现实中会有很多网页使用了AJAX, 比如百度搜索框,百度账号注册时的提示,还有淘宝充话费弹出来的框等等,核心思想就是"懒加载".

1.2 XML 简介

XML 可扩展标记语言
XML 被设计用来传输和存储数据
XML 和 HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示一些数据.
比如说我又一个学生数据:
name="孙悟空";age=18;gender="男";
用XML表示:

<student>
	<name>孙悟空</name>
	<age>18</age>
	<gender>男</gender>
</student>

现在已经被JSON替代了.
用JSON表示:

{"name":"孙悟空","age":18,"gender":"男"}

1.3 AJAX的特点

1.3.1 AJAX的优点

  1. 可以无需数显页面与服务器端进行通讯.
  2. 允许你根据用户事件来更新部分页面内容.

1.3.2 AJAX的缺点

  1. 没有浏览历史,不能后退.
  2. 存在跨域问题(同源),跨域指的是从一个服务向另外一个服务发送请求,可以解决.
  3. SEO不友好,SEO为(搜索引擎优化),因为网页中许多内容是通过AJAX请求服务再生成的内容,所以不会在源码中体现.

1.4 HTTP

HTTP(hypertext transport protocol)协议 超文本传输协议,协议详细规定了浏览器和万维网服务器之间互相通信的规则.
协议是一种约定和规则.

1.4.1 请求报文

格式与参数

请求行: 请求类型
GET 和 POST /s?ie=utf-8
HTTP/1.1
请求头:
Host:atguigu.com
Cookie:name=guigu
Content-type:application/x-www-from-urlencoded
User-Agent: chrome 83
空行:
请求体:
GET是空的,POST可以不是空的
username=admin&password=admin

1.4.2 响应报文

行: 协议版本HTTP/1.1 响应状态码200 响应状态字符串OK
头:
	Content-type: text/html;charset=utf-8
	Content-length: 2048
	Content-encoding:gzip

空行
体:  <html>
		<head>
		</head>
		<body>
			<h1>尚硅谷</h1>
		</body>
	 <html>

常见状态码:

  • 404 找不到
  • 403 被禁止
  • 401 未授权
  • 500 内部错误
  • 200 OK

1.4.3 如何在控制台看到HTTP的响应报文和请求报文呢?

以chrome为例,按F12键->点击Network->F5刷新页面->点击Name中对应的内容->右侧Headers栏中Response Headers 和Request Headers即为响应行\响应头和请求头,Query String Parameters为对url参数的解析,From data中能够看到请求体的内容,Response栏中内容为响应体.
通过view source可以查看源码信息.

1.5 express的基本使用

首先在vscode的资源管理器空白处右键,在集成终端中打开,然后输入:npm init --yes,npm是JS平台下的一个包管理工具,再安装一下express框架:npm i express,然后就可以在js中引入express使用了.
我们新建一个js文件,然后对express进行基本的配置.

//  1.引入express
 const express = require('express')
 // 2.创建应用对象
 const app = express();
 // 3.创建路由规则
 // request 是对请求报文的封装
 // response 是对响应报文的封装
 app.get('/',(request,response)=>{
    // 设置响应
    response.send("Hello EXPRESS");
 });

 // 4. 监听端口启动服务
 app.listen(8000,()=>{
     console.log("服务已经启动,8000 端口监听中...");
 })

可以看到我们的设置的响应体是Hello EXPRESS,然后我们开启一下服务,到文件的上一层右键,在集成终端中打开,然后输入ndoe express基本使用.js,即可启动服务,可以看到服务已经启动,8000 端口监听中...,说明服务启动成功,端口正在接听中,此时我们打开浏览器,输入127.0.0.1:8000,即可打开页面,可以看到Hello EXPRESS,然后我们进入开发者工具,就可以看到响应头\响应体和请求行\请求头,响应体的内容为Hello EXPRESS,然后我们就可以借助这个服务与前端的AJAX进行交互了.

1.6 AJAX请求发送前的准备

HTML代码

<!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>AJAX GET 请求</title>
    <style>
        #result{
            width: 200px;
            height:100px;
            border: solid 1px black;
        }
    </style>
</head>
<body>
    <button>点击发送请求</button>
    <div id="result"></div>
</body>
</html>

server.js代码

//  1.引入express
const express = require('express')
// 2.创建应用对象
const app = express();
// 3.创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 如果请求的url路径是请求行第二行的/server
// 这个时候就会执行回调函数里面的代码,并且由response回应
app.get('/server',(request,response)=>{
    // 设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 设置响应体
    response.send("Hello AJAX");
});

// 4. 监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000 端口监听中...");
})

当我们在上一层路径打开集成终端运行node server.js时,会发现报错,不出现服务已经启动的信息,原来此时我们8000端口已经用过了,我们需要将之前使用此端口的终端撤去,所以我们找到之前的终端,使用ctrl+c撤去,此时我们就可以正常启动服务了,然后我们在浏览器中输入:127.0.0.1:8000/server进入,便能看到HELLO AJAX的内容,再看一看请求头\响应头\响应体等内容此时案例准备就做好了.

1.7 AJAX请求的基本操作

现在我们想要实现一个功能,就是点击按钮时,将响应体的内容呈现出来,这个时候我们就需要修改js代码:

<script>
	// 获取btn元素
	const btn = document.getElementsByTagName("button")[0];
	const result = document.getElementById("result");
	// 绑定事件
	btn.onclick = function(){
		//1.创建对象
		const xhr = new XMLHttpRequest();
		// 2.初始化 设置请求方法和url
		xhr.open('GET','http://127.0.0.1:8000/server');
		// 3.发送
		xhr.send();
		// 4.事件绑定 处理服务端返回的结果
		// on when 当...时候
		// readystate 是xhr对象中的属性,表示状态
		// 0 被初始化
		// 1 open方法调用完毕 
		// 2 send方法调用完毕
		// 3 服务端返回了部分结果
		// 4 服务端返回了全部结果
		// change 改变的时候触发
		xhr.onreadystatechange = function(){
			//判断 (服务端返回了所有的结果)
			if(xhr.readyState == 4){
				// 判断响应状态码 200 404 403 401 500
				// 2xx 成功
				if(xhr.status >= 200 && xhr.status <300){
					//处理结果 行 头 空行 体
					//1. 响应行
					console.log(xhr.status);//状态码
					console.log(xhr.statusText);//状态字符串
					console.log(xhr.getAllResponseHeaders());//所有响应头
					console.log(xhr.response);//响应体
					//设置 result的文本
					result.innerHTML=xhr.response;
				}
			}
		}
	}
</script>

然后我们运行,再点击按钮,就发现已经可以获取到服务上的响应体了.在网页中按F12进入开发者工具,点击按钮,也能看到配置好server的各种信息.
image
注意:我们曾创建过一个常量xhr,在开发者工具中也能看到XHR,通常用来表示xmlHttpRequest,是开发者工具中筛选AJAX内容的区域.
image

1.8 如何给AJAX设置请求参数

如果要设置请求参数,就要在url后面加一个?,然后再带上参数,参数名=参数值,参数之间用&隔开,例如'http://127.0.0.1:8000/server?a=100&b=200&c=300'.
image

1.9 AJAX发送POST请求

现在我们的需求是创建一个div,设置一个边框和大小,然后当鼠标移入这个div区内时,发送POST请求,将服务商的请求体展示在里面,代码如下

<!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>AJAX POST 请求</title>
    <style>
        #result{
            width: 200px;
            height: 100px;
            border: solid 1px black;
        }
    </style>
</head>
<body>
   <div id="result"></div>
   <script>
       // 获取元素节点
       const result = document.getElementById("result");
       // 绑定事件
       result.addEventListener("mouseover",function(){
            // 1.创建对象
            const xhr = new XMLHttpRequest();
            // 2.初始化 设置类型与url
            xhr.open("POST",'http://127.0.0.1:8000/server');
            // 3.发送
            xhr.send();
            // 4.绑定
            xhr.onreadystatechange = function(){
                //对状态进行判断
                if(xhr.readyState == 4){
                    if(xhr.status >=200 && xhr.status < 300){
                        //处理服务端返回的结果
                        result.innerHTML = xhr.response;
                    }
                }
            }
       });
   </script>
</body>
</html>

我们重启一下服务,然后运行,发现并没有打到实际的效果,在开发者工具中查看,发现报错,此时我们发现原来我们的路由规则只是对get的处理,需要增加对post的处理,处理后的代码如下:

//  1.引入express
const express = require('express')
// 2.创建应用对象
const app = express();
// 3.创建路由规则
// request 是对请求报文的封装
// response 是对响应报文的封装
// 如果请求的url路径是请求行第二行的/server
// 这个时候就会执行回调函数里面的代码,并且由response回应
// get请求
app.get('/server',(request,response)=>{
    // 设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 设置响应体
    response.send("Hello AJAX GET");
});

// post请求
app.post('/server',(request,response)=>{
    // 设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin','*');
    // 设置响应体
    response.send("Hello AJAX POST");
});


// 4. 监听端口启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000 端口监听中...");
})

此时再运行,发现完美运行,再查看开发者工具,也是POST请求.
image

1.10 POST设置请求体

POST请求体中该如何设置参数呢?
xhr.send();中设置.

  • url参数形式.例如:xhr.send('a=100&b=200&c=300');.
  • 键值对形式.例如:xhr.send('a:100&b:200&c:300');.
  • 其实参数形式的设置要根据服务器能解析的形式来进行,只要服务器能够解析,那么就可以使用,甚至'123456789'都可以,只要有与之对应的处理方式.
    image

1.11 AJAX设置请求头信息

目前我们已经可以设置请求行信息和请求体信息了,那么如何给AJAX设置请求头信息呢?
我们在初始化xhr完毕后(即open函数调用完毕后)通过setRequestHeader()来设置,第一个参数为名称,第二个参数为值,例如:

// 设置请求头
// Content-Type:设置请求体内容类型
// application/x-www-form-urlencoded 参数查询字符串类型,为固定写法
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');

也可以设置自定义的请求头,但是服务中要添加all的路由规则和添加如下代码:

// 响应头  设置允许所有的请求头
response.setHeader('Access-Control-Allow-Headers','*');

当然这些自定义的不是前端应该做的工作,只是方便让大家理解.

posted @ 2021-09-26 12:15  bleaka  阅读(702)  评论(0编辑  收藏  举报