原生AJAX
1.1Ajax简介:
AJAX全称为:Asynchronous javaScript And XML 就是异步的js和xml
通过AjAx可以在浏览器中向服务器发送异步请求 最大的优点是无刷新获取数据
AjAx不是一种新的语言 而是将现有的标准组合起来的一种新的使用方式
1.2 XML简介
XML是可扩展标记语言
XML被用来传递和存储数据
XML和HTML很相似 但是HTML是预定义标签 而XML没有预定义标签大部分是自定义标签
1.3 AJAX特点:
优点:
无需刷新页面与服务器进行通信
允许你根据用户事件更新页面部分内容
缺点:
不能回退 没有浏览历史
存在跨域问题(后期可以使用JSONP、CORS解决跨域问题)
SEO不友好
1.4 AJAX的使用
核心对象:
XMLHttpRequest() AJAX的所有操作的基于该对象
使用步骤:
- 创建对象
const xml = new XMLHttpRequest()
- 设置请求信息
xml.open(method,url)
3.发送请求
xml.send()
4.处理事件
xhr.onreadystatechange = function (){
if(xhr.readyState == 4 && xhr.status == 200){
var text = xhr.responseText;
console.log(text);
}
}
xml.responseXML 接收相应数据
xhr.responseText 接收文本格式的响应数据
解决IE缓存性问题
由于浏览器的缓存机制,ajax只会发送一次请求 剩下的多次请求不会发送给浏览器而是直接加载缓存中的数据
解决方式:
xhr.open("get","/testAJAX?t="+Date.now());
AJAX的请求状态
xhr.readyState 查看当前请求状态
0:表示 XMLHttpRequest() 实例已经生成 但是open()方法没有调用
1:表示 send()方法还没有被调用,仍然可以使用 setRequestHeader(),设定 HTTP请求的头信息。
2:表示send()方法已经执行 并且头信息和状态码已经收到
3:表示接收服务器传来的body部分数据
4:表示服务器数据已经完全接收 或者接收失败
重点: 请求的前提是安装Node.js,配置环境
首先去官网下载node.js文件 Node.js官网 选择自己合适的窗口口下载
傻瓜式安装 直接下一步 安装过后 ,打开cmd 输入node -v 查看是否存在安装的版本号 如果存在 说明安装成功
原生AJAX请求案例
使用express框架创建的服务端,由于每次修改里面的内容需要重新请求服务器 所以推荐大家使用nodemon 插件 在Vscode中安装一下该插件 方便我们在修改服务端的时候 保存自动启动服务端
// 1.引入express文件
const { response } = require('express')
const express = require('express')
// 创建应用对象
const app = express()
// 创建路由规则
// request是对请求报文的封装
// response是对响应报文的封装
app.get('/server', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*')
// 响应头
response.setHeader('Access-Control-Allow-Headers', '*')
// 设置响应
response.send('HELLO AJAX-2')
})
// app.post('/server', (request, response) => {
// // 设置响应头 设置允许跨域
// response.setHeader('Access-Control-Allow-Origin', '*')
// // 设置响应
// response.send('HELLO AJAX POST')
// })
//可以接受所有类型的请求
app.all('/server', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*')
// 响应头
response.setHeader('Access-Control-Allow-Headers', '*')
// 设置响应
response.send('HELLO AJAX POST')
})
app.all('/json-server', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*')
// 响应头
response.setHeader('Access-Control-Allow-Headers', '*')
// 响应一个数据
const data = {
name: '张三'
}
// 对对象进行字符串的转换
let str = JSON.stringify(data)
// 设置响应
response.send(resultstr)
})
// 针对IE缓存问题
app.get('/ie', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*')
// 响应头
response.setHeader('Access-Control-Allow-Headers', '*')
// 设置响应
response.send('HELLO IE')
})
// 超时响应
app.get('/delay', (request, response) => {
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*')
// // 响应头
// response.setHeader('Access-Control-Allow-Headers', '*')
// 设置响应
setTimeout(() => {
response.send('延时响应')
}, 3000)
})
// 监听端口启动服务
app.listen('8000', () => {
console.log('服务器已经启动,8000端口监听中');
})
以下是客户端请求的案例
1.使用AJAX GET请求
<!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: 200px;
border: 1px solid lightgreen;
}
</style>
</head>
<body>
<button>点击发送请求</button>
<div id="result"></div>
<script>
// 获取元素
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?a=100&b=400&c=300')
//3. 发送
xhr.send()
// onreadystatechange:当状态发生变化的时候
xhr.onreadystatechange = function () {
// 判断(服务器返回所有的结果)
if (xhr.readyState === 4) {
// 判断响应状态码200 404 403 401 500
if (xhr.status >= 200 && xhr.status < 300) {
// 处理结果
// console.log(xhr.status); //状态码
// console.log(xhr.statusText); //状态字符串
// console.log(xhr.getAllResponseHeaders()); // 所有响应头
// console.log(xhr.response); //响应体
// 设置result的文本
result.innerHTML = xhr.response
}
}
}
}
</script>
</body>
</html>
2.使用AJAX 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: 200px;
border: 1px solid lightpink;
}
</style>
</head>
<body>
<div id="result">
</div>
<script>
// 获取元素
const result = document.getElementById('result')
// 绑定事件
result.onmouseover = function () {
//1.创建对象
const xhr = new XMLHttpRequest()
// 2.初始化 设置请求方法和url
xhr.open('POST', 'http://127.0.0.1:8000/server')
// 设置请求头
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.setRequestHeader('name', 'baidu')
// 3.发送
xhr.send()
// xhr.send('a=100&b=200&c=300')
// xhr.send('a:100&b:200&c:300')
// 4.事件绑定
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response
}
}
}
}
</script>
</body>
</html>
3.使用AJAX JSON响应
<!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>JSON响应</title>
<style>
#result {
width: 200px;
height: 200px;
border: 1px solid palevioletred;
}
</style>
</head>
<body>
<div id="result"></div>
<script>
const result = document.getElementById('result')
// 绑定键盘按下事件
window.onkeydown = function () {
// 发送请求
const xhr = new XMLHttpRequest()
// 设置响应体数据类型
xhr.responseType = "json"
// 初始化
xhr.open('get', 'http://127.0.0.1:8000/json-server')
// 发送
xhr.send()
// 事件绑定
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
// result.innerHTML = xhr.response
// 手动转换数据类型
// let data = JSON.parse(xhr.response)
// console.log(data);
// result.innerHTML = data.name
// 自动转换数据类型
result.innerHTML = xhr.response.name;
}
}
}
}
</script>
</body>
</html>
4. IE缓存性问题
<!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>IE缓存问题</title>
<style>
#result {
width: 200px;
height: 200px;
border: 1px solid lightcoral;
}
</style>
</head>
<body>
<button>点击我发送请求</button>
<div id="result">
</div>
<script>
const btn = document.getElementsByTagName('button')[0]
const result = document.getElementById('result')
btn.onclick = function () {
const xhr = new XMLHttpRequest()
xhr.open('get', 'http://127.0.0.1:8000/ie?t=' + Date.now())
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response
}
}
}
}
</script>
</body>
</html>
5.超时与网络异常
<!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>超时与网络异常</title>
<style>
#result {
width: 200px;
height: 200px;
border: 1px solid green;
}
</style>
</head>
<body>
<button>点击发送请求</button>
<div id="result"></div>
<script>
const btn = document.getElementsByTagName('button')[0]
const result = document.getElementById('result')
btn.onclick = function () {
const xhr = new XMLHttpRequest()
// 超时设置 2s 取消请求
xhr.timeout = 2000
// 超时回调
xhr.ontimeout = function () {
alert('网路异常,请稍后尝试')
}
// 网络异常的回调
xhr.onerror = function () {
alert('你的网络似乎存在问题')
}
xhr.open('get', 'http://127.0.0.1:8000/delay')
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response
}
}
}
}
</script>
</body>
</html>
6.取消请求
<!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>取消请求</title>
</head>
<body>
<button>发送请求</button>
<button>取消请求</button>
<script>
const btns = document.querySelectorAll('button')
let x = null
btns[0].onclick = function () {
x = new XMLHttpRequest()
x.open('get', 'http://127.0.0.1:8000/delay')
x.send()
}
btns[1].onclick = function () {
// 发送取消
x.abort()
}
</script>
</body>
</html>
7.重复请求
<!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>重复请求问题</title>
</head>
<body>
<button>发送请求</button>
<script>
const btns = document.querySelectorAll('button')
let x = null
let isSending = false
btns[0].onclick = function () {
// 判断标识变量
if (isSending) x.abort() // 如果正在发送 就取消该请求 创建一个新的请求
x = new XMLHttpRequest()
// 修改标识变量的值
isSending = true
x.open('get', 'http://127.0.0.1:8000/delay')
x.send()
x.onreadystatechange = function () {
if (x.readyState === 4) {
// 修改标识变量
isSending = false
}
}
}
</script>
</body>
</html>