AJAX入门
B站【尚硅谷】3小时Ajax入门到精通
https://www.bilibili.com/video/BV1WC4y1b78y
原生AJAX方法
0. 后端准备(express)
//引入express并创建应用对象
const express = require('express')
const app = express()
//创建路由规则
app.get('/', (requesr, response)=>{
//设置响应
response.send('hello express')
})
//监听端口启动服务
app.listen(8000, ()=>{
console.log('服务已经启动,端口8000监听中')
})
1. GET请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 200px;
height: 160px;
border: 1px solid #cd6969;
}
</style>
</head>
<body>
<!-- 需求:点击发送请求,将相应信息返回显示至ajax中 页面不刷新 -->
<button>点击发送请求</button>
<div id="res"></div>
<script>
const btn = document.getElementsByTagName('button')
const result = document.getElementById('res')
btn[0].onclick = function (){
//创建对象
const xhr = new XMLHttpRequest()
//设置请求方法和url
xhr.open('GET', 'http://localhost:8000/server')
//发送
xhr.send()
//事件绑定 处理服务端返回的结果
xhr.onreadystatechange = function (){
if(xhr.readyState === 4){ //服务端返回了所有结果
if(xhr.status >= 200 && xhr.readyState<=300){ //2开头的都表示成功
//处理结果
console.log(xhr.status) //状态码
console.log(xhr.statusText) //状态字符串
console.log(xhr.getAllResponseHeaders) //所有响应头
console.log(xhr.response) //响应体
result.innerHTML = xhr.response
}else{
}
}
}
}
</script>
</body>
</html>
2. POST请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 200px;
height: 150px;
border:1px solid #cd6969
}
</style>
</head>
<body>
<div id="res"></div>
<script>
const result = document.getElementById('res')
result.onmouseover = function(){
const xhr = new XMLHttpRequest()
xhr.open('POST', 'http://localhost:8000/server')
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send('a=100&b=200&c=3')
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status<300){
result.innerHTML = xhr.response
}
}
}
}
</script>
</body>
</html>
服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。
application/x-www-form-urlencoded 这应该是最常见的 POST 提交数据的方式了。
浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 这里设置请求头,可以自定义属性,不过,后端也要做修改
xhr.setRequestHeader('name','mrbird');
// 后端需要同步修改,设置头信息,*表示所有类型的头信息我多可以接收
response.setHeader('Access-Control-Allow-Headers', '*');
一般会把身份校验的信息放在请求头里面。
3. 服务端相应json
前段
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 200px;
height: 150px;
border: 1px solid #cd6969;
}
</style>
</head>
<body>
<div id="res"></div>
<script>
const result = document.getElementById('res')
window.onkeydown = function(){
const xhr = new XMLHttpRequest()
//设置响应体数据的类型
xhr.responseType = 'json'
xhr.open('GET', 'http://localhost:8000/json-server')
xhr.send()
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status>=200 && xhr.status<300){
console.log(xhr.response)
//手动对数据进行转换
// let data = JSON.parse(xhr.response)
// console.log(data)
//自动转换 (配合上面的设置响应体数据类型)
console.log(xhr.response)
result.innerHTML = xhr.response.name
}
}
}
}
</script>
</body>
</html>
后端
//创建路由规则
app.get('/json-server', (requesr, response)=>{
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*')
//相应一个数据
const data = {
name:'mrbird'
}
//对对象进行字符串转化
let str = JSON.stringify(data)
//设置响应
response.send(str)
})
4. IE缓存问题
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 200px;
height: 150px;
border: 1px solid #cd6969;
}
</style>
</head>
<body>
<button>点击发送请求</button>
<div id="res"></div>
<script>
const btn = document.getElementsByTagName('button')[0]
const result = document.getElementById('res')
btn.addEventListener('click', function(){
const xhr = new XMLHttpRequest()
// 这里用get方法,将时间戳写在url中,这样ie会认为这是2次不同的请求
xhr.open('GET', 'http://localhost: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>
后端
//创建路由规则
app.get('/ie', (requesr, response)=>{
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*')
//设置响应
response.send('hello ie -5')
})
5.请求超时与网络异常
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div{
width: 200px;
height: 150px;
border: 1px solid #cd6969;
}
</style>
</head>
<body>
<button>点击发送请求</button>
<div id="res"></div>
<script>
const btn = document.getElementsByTagName('button')[0]
const result = document.getElementById('res')
btn.addEventListener('click', function(){
const xhr = new XMLHttpRequest()
//超时设置 2秒还没有response回来,就会将请求取消
xhr.timeout = 2000
//超时回调
xhr.ontimeout = function (){
alert('网络异常,建议换台电脑')
}
//网络异常回调
xhr.onerror = function(){
alert('你的网络异常')
}
xhr.open('GET', 'http://localhost: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>
后端
//创建路由规则
app.all('/delay', (requesr, response)=>{
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*')
response.setHeader('Access-Control-Allow-Headers', '*')
//设置响应
setTimeout(()=>{
response.send('延时相应')
}, 3000)
})
6. 取消请求
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>发送请求</button>
<button>取消请求</button>
<script>
const btns = document.querySelectorAll('button')
let xhr = null
btns[0].onclick = function(){
xhr = new XMLHttpRequest()
xhr.open('GET', 'http://localhost:8000/delay')
xhr.send();
}
//取消请求的回调函数 注意需要将xhr放在外侧
btns[1].onclick = function(){
xhr.abort()
}
</script>
</body>
</html>
7. AJAX重复发送请求问题
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>发送请求</button>
<button>取消请求</button>
<script>
const btns = document.querySelectorAll('button')
let xhr = null
let isSending = false //是否正在发送Ajax请求
btns[0].onclick = function(){
if(isSending){
xhr.abort() //如果正在发送就取消请求,并创建一个新的请求
}
xhr = new XMLHttpRequest()
isSending = true
xhr.open('GET', 'http://localhost:8000/delay')
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
isSending = false
}
}
}
//取消请求的回调函数 注意需要将xhr放在外侧
btns[1].onclick = function(){
xhr.abort()
}
</script>
</body>
</html>
JQuery中的AJAX
前端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
h2{
width: 1200px;
margin: 50px auto 20px;
padding-bottom:10px ;
font-size: 30px;
border-bottom:1px solid gray ;
}
button{
border-radius: 5px;
height: 35px;
width: 100px;
background-color: blueviolet;
float: left;
margin-right: 10px;
color: white;
border: none;
text-align: center;
}
.btn-primary{
margin-left: 160px;
background-color: #cd6969;
}
.btn-danger{
background-color: orange;
}
</style>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<h2>jQuery发送Ajax请求</h2>
<button class="btn btn-primary">GET</button>
<button class="btn btn-danger">POST</button>
<button class="btn btn-info">通用型方法</button>
<script>
$('button').eq(0).click(function(){
$.get('http://localhost:8000/jquery-server', {a:100, b:200}, function(data){
console.log(data)
}, 'json')
// 加上了json,是指定响应体为json格式,会自动解析;不加的话,默认按照字符串解析
})
$('button').eq(1).click(function(){
$.post('http://localhost:8000/jquery-server', {a:100, b:200}, function(data){
console.log(data)
})
})
$('button').eq(2).click(function(){
$.ajax({
//url 给谁发
url:'http://localhost:8000/jquery-server',
//参数 对象
data:{a:100, b:200},
//请求类型
type:'GET',
//响应体结果
dataType:'json',
//成功的回调
success:function(data){
console.log(data)
},
//超时时间
timeout:2000,
//失败的回调
error:function(){
console.log('出错了')
},
//头信息设置
headers:{
c:300,
d:400
}
})
})
</script>
</body>
</html>
后端
//jquery 服务
app.all('/jquery-server', (requesr, response)=>{
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*')
response.setHeader('Access-Control-Allow-Headers', '*')
const data = {name:'hanser'}
//设置响应
response.send(JSON.stringify(data))
})