原生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.3.2 AJAX的缺点
- 没有浏览历史,不能后退.
- 存在跨域问题(同源),跨域指的是从一个服务向另外一个服务发送请求,可以解决.
- 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的各种信息.
注意:我们曾创建过一个常量xhr,在开发者工具中也能看到XHR,通常用来表示xmlHttpRequest,是开发者工具中筛选AJAX内容的区域.
1.8 如何给AJAX设置请求参数
如果要设置请求参数,就要在url后面加一个?,然后再带上参数,参数名=参数值,参数之间用&隔开,例如'http://127.0.0.1:8000/server?a=100&b=200&c=300'
.
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请求.
1.10 POST设置请求体
POST请求体中该如何设置参数呢?
xhr.send();
中设置.
- url参数形式.例如:
xhr.send('a=100&b=200&c=300');
. - 键值对形式.例如:
xhr.send('a:100&b:200&c:300');
. - 其实参数形式的设置要根据服务器能解析的形式来进行,只要服务器能够解析,那么就可以使用,甚至
'123456789'
都可以,只要有与之对应的处理方式.
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','*');
当然这些自定义的不是前端应该做的工作,只是方便让大家理解.