=## 原生AJAX
一、AJAX GET请求的基本操作
- 创建 GET.html 和 server.js 文件
- 在server.js 中设置响应头和响应内容
app.get('/server',(request, response)=>{
// 设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
// 设置响应
response.send('Hello!')
})
- GET.html中获取按钮节点,点击按钮触发事件,向服务器发送请求,获取数据
//获取button元素
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.事件绑定 处理服务端返回的结果
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response // 设置result的文本
} else {
}}}
-
readystate 是 xhr 对象中的属性,表示状态五个阶段:
- 0 初始值
- 1 open方法调用完毕
- 2 send方法调用完毕
- 3 服务端返回部份结果
- 4 服务端返回所有结果
-
xhr 对象的其它属性:(行、头、空行、体) xhr.status => 状态码(200 404 403 401 500) xhr.statusText => 状态字符串 xhr.getAllResponseHeaders() => 所有响应头 xhr.response => 响应体
- AJAX GET请求里设置参数的方式: 在url地址后用 ? 开头,& 分隔多个参数
xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300')
发送请求后可在network中的Query String Parameters看到发送的参数详情。
二、AJAX POST请求的基本操作
- AJAX里的post请求:
xhr.open('POST','http://127.0.0.1:8000/server')
- server.js 中:
app.post('/server',(request, response)=>{
// 设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
// 设置响应
response.send(
`<h1>hi,I'm from POST</h1>`
)
})
- post请求该如何设置参数
xhr.send('a=100&b=200&c=300')
// xhr.send('a:100&b:200&c:300')
// xhr.send('hello')
三、设置请求头信息
在xhr.send()之前,使用setRequestHeader方法:
//设置请求头
xhr.setRequestHeader("","")
设置请求体内容(send内参数)的类型:
('Content-Type','applicaton/x-www-form-urlencoded')
设置名字
('name','atguigu')
遇到报错,是浏览器的安全机制,防止post发送任意类型的请求,解决方法是在server.js中:
// 可以接收任意类型的请求
app.all('/server',(request, response)=>{
// 设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
// 设置响应头
response.setHeader('Access-Control-Allow-Headers','*')
// 设置响应
response.send(
`<h1>hi,I'm from POST</h1>`
)
})
四、传递对象数据
- server.js中:
app.all('/json-server',(request, response)=>{
// 设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
// 设置响应头
response.setHeader('Access-Control-Allow-Headers','*')
// 响应一个数据
const data = {name:'atguigu'}
// 对对象进行字符串转换:
// let str = JSON.stringify(data)
// 设置响应
response.send(data)
})
- html文件中对接收到的data(字符串格式)进行转换: 手动转换:
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status <300){
// 手动转换:
let data = JSON.parse(xhr.response)
console.log(data); // 对象
result.innerHTML = data.name
}}}
自动转换:
// 设置响应体数据的类型:
xhr.responseType = 'json'
...
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status <300){
// 自动转换
console.log(xhr.response); // 对象
result.innerHTML = xhr.response.name
}}}
五、解决IE浏览器的缓存问题:
在初始化请求方法和url中:
xhr.open("GET",'http://127.0.0.1:8000/ie?t='+Date.now())
url加上了 ?t= , 再加Date.now()
六、请求超时与网络异常
- 请求超时 1.在server中用setTimeout设置延时:
app.get('/delay',(request, response)=>{
// 设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*')
setTimeout(()=>{
// 设置响应
response.send('延时响应')
},3000)
})
2.在html中设置2秒的超时, xhr.timeout 为自动取消的时间限制;ontimeout 方法,为当超过时间限制时调用的函数:
const xhr = new XMLHttpRequest()
// 超时自动取消 2s 设置
xhr.timeout = 2000
// 超时回调
xhr.ontimeout = function(){
result.innerHTML = '网络异常,请稍后重试'
// alert('网络异常,请稍后重试')
}
- 网络异常回调,onerror 方法 :
xhr.onerror = function(){
result.innerHTML = '对不起,您的网络异常,请检查网络'
}
七、手动取消
.abort() 方法
html(注意x需要在函数外部先赋一个空值):
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()
}
八、重复请求问题
建立一个标识变量 isSending
const btns = document.querySelectorAll('button')
let x = null
// 标识变量
let isSending = false; // 是否正在发送AJAX请求
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 // 修改标识变量的值
}
}
}