一.原生AJAX
1.什么是ajax
AJAX全程为Asynchronous Javascript And XML,异步的js和XML
通过AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
语言
可扩展标记语言。XML被设计用来传输和存储数据。XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全部都是自定义标签,用来表示一些数据。(目前已经被JSON取代)
特点:
优点:
(1)可以无需刷新页面而与服务器端进行通信。
(2)允许你根据用户事件(鼠标事件,文档事件)来更新部分页面内容。
缺点:
(1)没有浏览历史,不能回退。
(2)存在跨域问题(同源)
(3)SEO不友好(查看源代码中无法查找到)
二.HTTP协议
HTTP全称为hypertext transport protocol 协议【超文本传输协议】,协议详细规定了浏览器和万维网服务器之间互相通信的规则。约定了请求和响应格式与参数
请求报文:Request Headers
行:请求类型(get,post) / url类型() / HTTP协议版本 /
头:Host:值
Cookie: 值
Content-type:值
User-Agent:值
空行:固定的
体:如果是GET请求体为空,如果是POST可以不为空
响应报文:Response Headers
行: HTTP协议版本(1.1) / 响应状态(200) /响应状态字符串(ok)
头:Content-type:值
Content-length:值
Content-encoding:值
等等
空行:
体:HTML语法内容
三.AJAX环境配置
1.下载安装配置环境
下载安装node.js后需要安装,只需要在vscode => 终端 => 当前目录中 => 输入npm i express;
然后引入express,
-
// 1.引入express
-
const express = require('express');
-
// 2.创建应用对象
-
const app = express();
-
// 3.创建路由规则
-
//request封装请求报文
-
//response封装响应报文
-
app.get('/', (request, response) => {
-
//设置响应
-
response.send('HELLO EXPRESS')
-
});
-
-
//4.监听端口启动服务
-
(8000, () => {
-
('服务已启动,8000端口监听中。。。。。');
-
})
然后浏览器输入:127.0.0.1:8000可以看到响应信息
当出现端口被占用报错时: address already in use :::8000或者如下图node时,可使用ctrl+c实现端口释放
四.AJAX发送请求
1.发送请求准备
-
<head>
-
<meta charset="UTF-8">
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
-
<title>Document</title>
-
<style>
-
.box {
-
width: 200px;
-
height: 100px;
-
border: 1px solid #60cc;
-
}
-
</style>
-
</head>
-
-
<body>
-
<button>发送</button>
-
<div class="box"></div>
-
</body>
-
// 1.引入express
-
const { response } = require('express')
-
const express = require('express')
-
// 2.创建应用对象
-
const app = express()
-
// 3.创建路由规则
-
app.get('/server', (request, response) => {
-
//设置响应头 设置允许跨域
-
('Access-Control-Allow-Origin', '*');
-
//设置响应体
-
response.send('HELLO AJAX')
-
})
-
// 4.监听端口启动服务
-
(8000, () => {
-
('服务已启动,8000端口监听中。。。。。');
-
})
发送Get请求
-
<style>
-
.box {
-
width: 200px;
-
height: 100px;
-
border: 1px solid #60cc;
-
}
-
</style>
-
<button>发送</button>
-
<div class="box"></div>
server.js
-
// 1.引入express
-
const express = require('express')
-
// 2.创建应用对象
-
const app = express()
-
// 3.创建路由规则
-
app.get('/server', (request, response) => {
-
//设置响应头 设置允许跨域
-
('Access-Control-Allow-Origin', '*');
-
//设置响应体
-
response.send('HELLO AJAX')
-
})
-
// 4.监听端口启动服务
-
(8000, () => {
-
('服务已启动,8000端口监听中。。。。。');
-
})
点击发送将响应体添加到文本框获取文本
onreadystatechange:on当...时; readystate是xhr对象中的属性,表示状态0 1 2 3 4
change改变
其中0 为未初始化 ;1为 open调用完毕 ;2 :send调用完毕 3 :服务端返回了部分结果 4: 服务端返回了所有结果
-
<script>
-
// 获取button元素\
-
const btn = ('button')[0]
-
const result = ('.box')
-
//绑定事件
-
= function () {
-
// 1.创建对象
-
const xhr = new XMLHttpRequest()
-
//2初始化 设置请求请求方法和url
-
xhr.open('GET', 'http://127.0.0.1:8000/server')
-
// 3.发送
-
xhr.send();
-
// 4.事件绑定,处理服务端返回的结果
-
//on当...时; readystate是xh对象中的属性,表示状态0 1 2 3 4 change改变
-
// 其中0 - 未初始化 1 - open调用完毕 2 - send调用完毕 3 - 服务端返回了部分结果 4 - 服务端返回了所有结果
-
= function () {
-
// 判断(假设服务端返回了所有结果)
-
if ( === 4)
-
// 判断响应状态 200 404 403 500
-
// 2开头的响应状态均为成功 203 201
-
if (xhr.status >= 200 && xhr.status < 300) {
-
//处理结果 行 头 空行 体
-
// 1.响应行
-
/* (xhr.status);//状态码
-
();//状态字符串
-
(());//所有响应头
-
();//响应体 */
-
// 设置box内文本
-
=
-
}
-
}
-
}
-
</script>
get传递参数:在url后缀参数,使用 ?分隔,=赋值,比如 ?a=100&b=200&c=300
发送post请求
-
<style>
-
-
.result {
-
-
width: 200px;
-
-
height: 100px;
-
-
border: 1px solid red;
-
-
}
-
-
</style>
-
-
</head>
-
-
<body>
-
-
<div class="result"></div>
首先获取盒子,为其添加鼠标移动事件
然后创建XMLHttpRequest对象;并初始化为其设置请求方法和url
通过 设置请求头
然后发送请求,post传递参数放入send()内
接着对其进行事件绑定onreadystetechange,处理服务端返回的结果;
首先判断是否等于4,即服务端返回了所有结果状态,
若等于4则在判断响应状态是否为200,即正确响应
在将响应的信息通过innerHTML添加到盒子内
-
<script>
-
const result = ('.result')
-
('mouseover', function () {
-
// 1.创建对象
-
const xhr = new XMLHttpRequest()
-
//2。初始化,设置请求类型和url
-
xhr.open('POST', 'http://127.0.0.1:8000/server');
-
// 设置请求头 Content-Type设置请求体类型,也可以自己定义但会报错
-
// application/x-www-form-urlencoded参数查询字符串固定写法
-
('Content-Type', 'application/x-www-form-urlencoded')
-
// 3.发送
-
//post请求设置参数
-
xhr.send('a=100&b=200&c=300');
-
// 4.事件绑定 处理服务端返回的结果
-
= function () {
-
if ( === 4) {
-
if (xhr.status >= 200 && xhr.status < 300) {
-
=
-
}
-
}
-
}
-
-
})
-
-
</script>
然后在内添加post路由规则
-
// 1.引入express
-
const express = require('express')
-
// 2.创建应用对象
-
const app = express()
-
// 3.创建get路由规则
-
app.get('/server', (request, response) => {
-
//设置响应头 设置允许跨域
-
('Access-Control-Allow-Origin', '*');
-
//设置响应体
-
response.send('HELLO AJAX')
-
-
})
-
// 3.创建post路由规则 all可以接受任意类型的请求
-
app.all('/server', (request, response) => {
-
//设置响应头 设置允许跨域
-
('Access-Control-Allow-Origin', '*');
-
// 设置响应头
-
('Access-Control-Allow-Headers', '*');
-
//设置响应体
-
response.send('HELLO AJAX POST')
-
-
})
-
// 4.监听端口启动服务
-
(8000, () => {
-
('服务已启动,8000端口监听中。。。。。');
-
})
响应发送对象数据
当响应一个对象数据时,需要通过()对对象数据进行字符串转换,然后将转换后的字符串添加到响应体
-
app.all('/json-server', (request, response) => {
-
//设置响应头 设置允许跨域
-
('Access-Control-Allow-Origin', '*');
-
// 设置响应头
-
('Access-Control-Allow-Headers', '*');
-
-
// 响应一个数据
-
const data = {
-
name: 'lalala'
-
};
-
// 对对象数据进行字符串转换
-
let str = (data)
-
//设置响应体
-
response.send(str)
-
-
}
当服务器转换结果为字符串时,页面无法识别,所以这时需要将json字符串转换为js对象;有以下方法:
(1)手动对数据进行转化
-
let data = JSON.parse(xhr.response)
-
= data.name
(2)通过自动转换
设置响应体数据类型
= 'json'
-
console.log(xhr.response);
-
= xhr.response.name
五.AJAX问题
缓存问题
-
app.get('/ie', (request, response) => {
-
//设置响应头 设置允许跨域
-
('Access-Control-Allow-Origin', '*');
-
//设置响应体
-
response.send('HELLO IE-3')
-
})
当你响应体改变时,IE不会更新,而是走缓存,还是上一次的响应体;解决方法是在url后面添加时间戳,使每次的url都不一样,这样就不会出现改变响应体时IE走缓存不更新的问题
xhr.open('GET', 'http://127.0.0.1:8000/ie?t=' + Date.now())//Date.now()获取当前时间戳
2.请求超时与网络异常处理
服务端写个定时函数,三秒后向页面传递响应体
-
//针对超时响应的
-
app.get('/delay', (request, response) => {
-
//设置响应头 设置允许跨域
-
('Access-Control-Allow-Origin', '*');
-
setTimeout(() => {
-
//设置响应体
-
response.send('延时响应')
-
}, 3000)
-
})
在页面进行超时设置,可以设置超时和超时回调
,还有网络异常回调
-
// 超时设置 2秒内还没有接受到响应体则取消请求
-
= 2000
-
//超时回调
-
= function () {
-
alert('网络不太好再等等!')
-
}
-
//网络异常回调
-
= function () {
-
alert('你的网络似乎出现问题了')
-
}
手动取消请求
上面通过自动取消请求,下面介绍手动取消请求:
通过()方法取消请求,作用域的问题,把xhr定义在外边给个null,然后赋值xhr实例,再调用方法。(重复赋值不要用const噢,能用const就用const,不能const就let)
-
<button>点击发送</button>
-
<button>点击取消</button>
-
<script>
-
const btns = ('button')
-
let xhr = null
-
btns[0].onclick = function () {
-
xhr = new XMLHttpRequest();
-
xhr.open('GET', 'http://127.0.0.1:8000/delay')
-
xhr.send(); //不用拿响应体,所以后边儿不写了
-
}
-
-
//取消请求,abort方法
-
btns[1].addEventListener('click', function () {
-
(); //先点send再点cancel不会报错,先点cancel报错
-
(xhr); //先点send再点cancel是xhr实例,先点cancel报错
-
})
4.请求重复发送问题
用户多次点击发送按钮时,判断标识量isSending判断是否正在发送请求,若正在发送,取消此次的请求,创建新请求
不知道为啥()一直报错!!!!!(好像是chrome不支持本地的ajax导致的,换个浏览器好了)
-
<button>点击发送</button>
-
-
<script>
-
const btns = ('button');
-
let xhr = null;
-
//标识变量,判断是否发送AJAX请求
-
let isSending = false;
-
btns[0].onclick = function () {
-
// 判断标识量 如果正在发送请求,则再次点击后取消该请求,创建一个新请求
-
if (isSending) ()
-
xhr = new XMLHttpRequest();
-
isSending = true;
-
xhr.open('GET', 'http://127.0.0.1:8000/delay')
-
xhr.send()
-
= function () {
-
if ( === 4) {
-
// 修改标识量 发送完毕后停止发送
-
isSending = false
-
}
-
}
-
-
}
-
-
</script>