AJAX 简介:
AJAX 全称为 Asynchronous JavaScript And XML
,就是异步的 JS 和 XML。
通过 AJAX
可以在浏览器中向服务器发送异步请求
,最大的优势:无刷新获取数据。
AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式
AJAX 的特点
- 可以无需刷新页面而与服务器端进行通信。
- 允许你根据用户事件来更新部分页面内容。
- 没有浏览历史,不能回退
- 存在跨域问题(同源)
- SEO 不友好
AJAX案例
index.html
<button>点击发送请求</button>
<div id="result"></div>
<script src="./index.js"></script> //注意,此处放后
index.css
#result {
width: 200px;
height: 100px;
border: solid 2px blue;
}
AJAX发送GET请求
index.js
const btn = document.getElementsByTagName('button')[0];
btn.onclick = function () {
//1.创建对象
const xhr = new XMLHttpRequest()
//2.初始化,设置请求方法和url get请求参数直接放这
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200')
//3.发送
xhr.send()
//4.时间绑定,处理服务器返回的结果
// on when 当....时候
// readystate 是 xhr 对象中的属性, 表示状态 0 1 2 3 4
/*
0 (未初始化): (XMLHttpRequest)对象已经创建,但还没有调用open()方法。
1 (载入):已经调用open() 方法,但尚未发送请求。
2 (载入完成): 请求已经发送完成。
3 (交互):可以接收到部分响应数据。
4 (完成):已经接收到了全部数据,并且连接已经关闭。
*/
// change 改变
xhr.onreadystatechange = function () {
//判断 (服务端返回了所有的结果)
if (xhr.readyState === 4) {
//判断响应状态码 200 404 403 401 500
// 2xx 成功
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;
}
}
}
}
server.js 设置服务器:需安装express
/*
npm init
npm i express
node express 启动服务器
*/
//1.引入express
const express = require('express')
//2.创建应用对象
const app = express()
//3.创建路由规则
//request 是对请求报文的封装
//response 是对相应报文的封装
//get请求的对应
app.get('/server', (request, response) => {
//设置响应头
response.setHeader('Access-Control-Allow-Origin', '*')
//设置响应体
response.send('Hello Express')
})
//4.监听端口启动服务
app.listen(8000, () => {
console.log('服务器已启动')
})
启动方法:
- 终端
node server.js
- 开启
index.html
AJAX发送POST请求
index.js
//获取元素对象
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()
// 有参数
// xhr.send('a=100&b=200&c=200')
//4.事件绑定
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response
}
}
}
})
server.js 中增加此处
app.post('/server', (request, response) => {
//设置响应头
response.setHeader('Access-Control-Allow-Origin', '*')
//设置响应体
response.send('Hello Express POST')
})
POST中如何设置请求头信息
index.js — setRequestHeader
//获取元素对象
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')
//此处设置请求头
//预定义 请求体的形式 固定的
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
//自定义
xhr.setRequestHeader('name', 'hfdsa')
//3.发送
xhr.send()
// 有参数
// xhr.send('a=100&b=200&c=200')
//4.事件绑定
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response
}
}
}
})
server.js
//可以接受任意类型的请求
app.all('/json-server', (request, response) => {
//设置响应头
response.setHeader('Access-Control-Allow-Origin', '*')
//设置响应头 -- 增加此处,允许自定义请求头信息
response.setHeader('Access-Control-Allow-Headers', '*')
//设置响应体
response.send('Hello Express JSON')
})
处理JSON格式数据
index.js
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) {
// console.log(xhr.response);
// result.innerHTML = xhr.response
//1.手动对数据进行转换
// let data = JSON.parse(xhr.response)
// result.innerHTML = data.nam
//2.自动转换
result.innerHTML = xhr.response.nam
}
}
}
}
server.js
/*
npm init
npm i express
node express 启动服务器
*/
//1.引入express
const express = require('express')
//2.创建应用对象
const app = express()
//3.创建路由规则
//request 是对请求报文的封装
//response 是对相应报文的封装
//get请求的对应
app.get('/server', (request, response) => {
//设置响应头
response.setHeader('Access-Control-Allow-Origin', '*')
//设置响应体
response.send('Hello Express')
})
//post请求的对应 app.post
//可以结束任意类型的请求
app.all('/json-server', (request, response) => {
//设置响应头
response.setHeader('Access-Control-Allow-Origin', '*')
//设置响应头
response.setHeader('Access-Control-Allow-Headers', '*')
const data = {
nam: 'hdhun'
}
//对数据格式化
let str = JSON.stringify(data)
//设置响应体
response.send(str)
})
//4.监听端口启动服务
app.listen(8000, () => {
console.log('服务器已启动')
})
请求超时和网络异常处理
index.js
const btn = document.getElementsByTagName('button')[0]
const result = document.getElementById('result')
//绑定键盘按下事件
btn.onclick = function () {
//创建对象
const xhr = new XMLHttpRequest();
//超时设置
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
}
}
}
}
server.js
/*
npm init
npm i express
node express 启动服务器
*/
//1.引入express
const express = require('express')
//2.创建应用对象
const app = express()
//3.创建路由规则
//request 是对请求报文的封装
//response 是对相应报文的封装
//get请求的对应
app.get('/server', (request, response) => {
//设置响应头
response.setHeader('Access-Control-Allow-Origin', '*')
//设置响应体
response.send('Hello Express -2')
})
//post请求的对应 app.post
//可以结束任意类型的请求
app.all('/json-server', (request, response) => {
//设置响应头
response.setHeader('Access-Control-Allow-Origin', '*')
//设置响应头
response.setHeader('Access-Control-Allow-Headers', '*')
const data = {
nam: 'hewan'
}
//对数据格式化
let str = JSON.stringify(data)
//设置响应体
response.send(str)
})
//get请求的对应
app.get('/delay', (request, response) => {
//设置响应头
response.setHeader('Access-Control-Allow-Origin', '*')
setTimeout(() => {
response.send('延时响应')
}, 3000)
})
//4.监听端口启动服务
app.listen(8000, () => {
console.log('服务器已启动')
})
取消请求
index.html
<button>点击发送请求</button>
<button>点击取消请求</button>
<script src='./js/index.js'></script>
index.js
const btns = document.querySelectorAll('button')
let xhr = null
btns[0].onclick = function () {
xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:8000/delay')
xhr.send()
}
btns[1].onclick = function () {
xhr.abort()
}
server.js
/*
npm init
npm i express
node express 启动服务器
*/
//1.引入express
const express = require('express')
//2.创建应用对象
const app = express()
//3.创建路由规则
//request 是对请求报文的封装
//response 是对相应报文的封装
//get请求的对应
app.get('/server', (request, response) => {
//设置响应头
response.setHeader('Access-Control-Allow-Origin', '*')
//设置响应体
response.send('Hello Express -2')
})
//get请求的对应
app.get('/delay', (request, response) => {
//设置响应头
response.setHeader('Access-Control-Allow-Origin', '*')
setTimeout(() => {
response.send('延时响应')
}, 3000)
})
//4.监听端口启动服务
app.listen(8000, () => {
console.log('服务器已启动')
})
重复请求
发送多个相同请求,服务器压力大
在发送请求时,判断之前是否也有请求在发送,如果有,取消前一个
index.js
const btns = document.querySelectorAll('button')
let xhr = null
let isSending = false //标识变量:是否在发送AJAX请求
btns[0].onclick = function () {
//如果正在发送请求,取消该请求
if (isSending) xhr.abort()
//创建新对象
xhr = new XMLHttpRequest();
//即将要发送请求,isSending改变
isSending = true
xhr.open('GET', 'http://127.0.0.1:8000/delay')
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyStste === 4) {
//请求成功了并完成了,修改isSending的值
isSending = false
}
}
}
btns[1].onclick = function () {
xhr.abort()
}
Axios发送AJAX请求
index.html
<button>GET</button>
<button>POST</button>
<button>AJAX</button>
index.js
const btns = document.querySelectorAll('button')
btns[0].onclick = function () {
axios.get('http://127.0.0.1:8000/axios-server', {
//url 参数
params: {
id: 100,
vip: 7
},
//请求头信息
headers: {
name: '夜夜夜',
age: 20
}
}).then((value) => {
console.log(value);
})
}
btns[1].onclick = function () {
//url data config
axios.post('http://127.0.0.1:8000/axios-server',
{
username: 'yeye',
password: '123456'
},
{
params: {
id: 200,
vip: 9
},
//请求头信息
headers: {
height: 183,
weight: 180
}
}
)
}
btns[2].onclick = function () {
axios({
//请求方法
method: 'POST',
//url
url: 'http://127.0.0.1:8000/axios-server',
//url参数
params: {
vip: 10,
level: 20
},
//头信息
headers: {
a: 100,
b: 200
},
//请求体参数
data: {
username: 'yeye',
password: '123456'
}
}).then(xhr => {
console.log(xhr);
console.log(xhr.status) //状态码
console.log(xhr.statusText); //状态字符串
console.log(xhr.headers) //所有响应头
console.log(xhr.data); //响应体
})
}
server.js
//axios服务
app.all('/axios-server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*')
response.setHeader('Access-Control-Allow-Headers', '*')
const data = { nam: 'hhisn' }
response.send(JSON.stringify(data))
})
fetch发送AJAX请求
index.html
<button>AJAX</button>
index.js
const btn = document.querySelector('button')
btn.onclick = function () {
fetch('http://127.0.0.1:8000/fetch-server', {
//请求方法
method: 'POST',
//请求头
header: {
name: '夜夜夜',
},
//请求体
body: 'username=yeyeye&password=123456',
}).then(response => {
return response.json();
}).then(response => {
console.log(response);
})
}
sever.js
//fetch服务
app.all('/fetch-server', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*')
response.setHeader('Access-Control-Allow-Headers', '*')
const data = { nam: 'hhisn' }
response.send(JSON.stringify(data))
})
跨域
原生JSONP
index.html
用户名:<input type="text" id="username">
<p></p>
<script src='./js/index.js'></script>
index.js
const input = document.getElementsByTagName('input')[0]
const p = document.getElementsByTagName('p')[0]
function handle(data) {
input.style.border = 'solid 2px green';
p.innerHTML = data.mes
}
input.onblur = function () {
//获取input用户名
let username = this.value;
//向服务器发送请求,检测账号是否存在
//1.创建一个script标签,进行跨域访问
const script = document.createElement('script')
//2.标签的script的src
script.src = 'http://127.0.0.1:8000/check-username'
//将script插入html
document.body.appendChild(script)
}
server.js
//check-username服务
app.all('/check-username', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*')
response.setHeader('Access-Control-Allow-Headers', '*')
const data = { exist: 1, mes: '该账号已经存在' }
let str = JSON.stringify(data)
response.end(`handle(${str})`)
})
CORS
MDN:HTTP访问控制
server.js中
app.all('/cors-server', (request, response)=>{
//设置响应头
response.setHeader("Access-Control-Allow-Origin", "*"); //此处
response.setHeader("Access-Control-Allow-Headers", '*'); //此处
response.setHeader("Access-Control-Allow-Method", '*');
// response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:5500");
response.send('hello CORS');
});