原生 AJAX
GET 请求
一. 实例要求:点击按钮,发送GET请求,在 div 中做呈现 HELLO AJAX
- 创建 server.js 文件
//1.引入express const express = require('express'); //2.创建应用对象 const app = express(); //3.创建路由规则 //requset是对请求报文的封装 //response是对相应报文的封装 app.get('/server', (request, response)=>{ // 设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin','*') //名字,值 // 设置响应体 response.send('HELLO AJAX') }); //4.监听端口启动服务 app.listen(8000, ()=>{ console.log("服务已经启动,8000 端口监听中..."); })
- 创建 1-GET.html 文件
<!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: 100px; border: solid 1px #90b; } </style> </head> <body> <button>点击发送请求</button> <div id="result"></div> <script> //获取button元素 const btn = document.getElementsByTagName('button')[0] //绑定事件 btn.onclick = function(){ // 1.创建对象 const xhr = new XMLHttpRequest() const result = document.getElementById("result") // 2.初始化 设置请求方法和 url ?后面为设置的请求参数 xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300') // 3.发送 xhr.send() // 4.事件绑定 处理服务端返回的结果 // on 当...时候 // readystate 是 xhr 对象中的属性 // 表示状态 0(未初始化) 1(open方法调用完毕) 2(send方法调用完毕) 3(服务端返回了部分结果) 4(服务端返回了所有结果) // change 改变 xhr.onreadystatechange = function(){ // 判断 (服务端返回了所有结果) if(xhr.readyState === 4){ //判断响应状态码 200 404 403 401 500 // 2XX 成功 if(xhr.status >= 200 && xhr.status < 300){ //处理结果 行 头 空行 体 // 1.响应行 // console.log(xhr.status); //状态码 // console.log(xhr.statusText); //状态字符串 // console.log(xhr.getAllResponseHeaders()); //所有响应头 // console.log(xhr.response); //响应体 //设置 result 的文本 result.innerHTML = xhr.response }else{ } } } } </script> </body> </html>
注意:现阶段,如果已经开启了一个服务,要把原先的服务关闭才能开启一个新服务
POST 请求
二. 实例要求:当鼠标移动到 div 上,发送POST请求,结果在 div 中做呈现 HELLO AJAX
- 修改 server.js 文件
//1.引入express const express = require('express'); //2.创建应用对象 const app = express(); //3.创建路由规则 //requset是对请求报文的封装 //response是对相应报文的封装 app.get('/server', (request, response)=>{ // 设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin','*') //名字,值 // 设置响应体 response.send('HELLO AJAX') }); // all可以接受任意类型的请求 app.all('/server', (request, response)=>{ // 设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin','*') //名字,值 // 响应头 response.setHeader('Access-Control-Allow-Headers','*') //*表示所有类型的头信息都接受 // 设置响应体 response.send('HELLO AJAX POST') }); //4.监听端口启动服务 app.listen(8000, ()=>{ console.log("服务已经启动,8000 端口监听中..."); })
- 创建 2-POST.html 文件
<!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: 100px; border: solid 1px #903; } </style> </head> <body> <div id="result"></div> <script> // 获取元素对象 const result = document.getElementById("result") // 绑定事件 result.addEventListener("mouseover", function(){ // console.log("test"); // 1.创建对象 const xhr = new XMLHttpRequest() // 2.初始化 设置类型 URL xhr.open('POST','http://127.0.0.1:8000/server') // 设置请求头 // Content-Type(预定义)用来设置请求体内容的类型 // application/x-www-form-urlencoded 参数查询字符串的类型,固定写法 xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded') xhr.setRequestHeader('name','WEB') // 3.发送 ()内设置 POST 请求体 xhr.send('a=100&b=200&c=300') //常用形式 // xhr.send('a:100&b:200&c:300') // xhr.send('123') // 4.事件绑定 xhr.onreadystatechange = function(){ // 判断 if(xhr.readyState === 4){ if(xhr.status >= 200 && xhr.status < 300){ // 处理服务端返回的结果 result.innerHTML = xhr.response } } } }) </script> </body> </html>
JSON 请求
三. 实例要求:键盘按下,发送请求,结果在 div 中做呈现 HELLO AJAX JSON(JSON响应)
1.修改 server.js 文件
//1.引入express const express = require('express'); //2.创建应用对象 const app = express(); //3.创建路由规则 //requset是对请求报文的封装 //response是对相应报文的封装 app.get('/server', (request, response)=>{ // 设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin','*') //名字,值 // 设置响应体 response.send('HELLO AJAX GET') }); // all可以接受任意类型的请求 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: 'HELLO AJAX JSON' } //对对象进行字符串转换 let str = JSON.stringify(data) // 设置响应体 response.send(str) }); //4.监听端口启动服务 app.listen(8000, ()=>{ console.log("服务已经启动,8000 端口监听中..."); })
- 创建 3-JSON.html 文件
<!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: 100px; border:solid 1px #89b; } </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){ // // console.log(xhr.response); // result.innerHTML = xhr.response // 1.手动对数据转化 /* let data = JSON.parse(xhr.response) console.log(data); result.innerHTML = data.name */ // 2.自动转换 console.log(xhr.response) result.innerHTML = xhr.response.name } } } } </script> </body> </html>
nodemon 自动启动工具
- 安装:终端输入 npm install -g nodemon
- 启动服务:终端输入 nodemon server.js
通过安装 nodemon 工具,在终端输入命令。这样再修改服务端代码时,就不用再重新启动服务了
IE 缓存问题
问题:在 IE 浏览器中,由于缓存机制,改变服务器发送的值时,页面并不会随之做出改变
解决方法:让每一个时间戳都刷新一次
具体写法:xhr.open("GET",'http://127.0.0.1:8000/ie?t=' + Date.now())
修改 server.js 文件
//1.引入express const express = require('express'); //2.创建应用对象 const app = express(); //3.创建路由规则 //requset是对请求报文的封装 //response是对相应报文的封装 app.get('/server', (request, response)=>{ // 设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin','*') //名字,值 // 设置响应体 response.send('HELLO AJAX GET') }); // all可以接受任意类型的请求 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: 'HELLO AJAX JSON2' } //对对象进行字符串转换 let str = JSON.stringify(data) // 设置响应体 response.send(str) }); // 针对 IE 缓存 app.get('/ie', (request, response)=>{ // 设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin','*') //名字,值 // 设置响应体 response.send('HELLO AJAX IE') }); //4.监听端口启动服务 app.listen(8000, ()=>{ console.log("服务已经启动,8000 端口监听中..."); })
- 创建 4-IE缓存问题.html 文件
<!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: 100px; border:solid 1px #258; } </style> </head> <body> <button>点击发送请求</button> <div id="result"></div> <script> const btn = document.getElementsByTagName('button')[0] const result = document.querySelector('#result') btn.addEventListener('click',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>
请求超时 和 网络异常处理
1.点击按钮,当请求超出两秒时,提示请求超时
2.当断掉网络时(第二图设置为offline),点击按钮,提示网络出问题了
- 请求超时:客户机先发出请求,服务器响应这个请求。如果这之间的软件或硬件有问题,那个这个请求可能无法送答服务器,或者送达到服务器但服务器无回应。
- 网络异常:网络错误的代词,发生网络异常后浏览器会就错误的类型显示错误代码,如404 503等等。
- 修改
server.js
文件
//1.引入express const express = require('express'); //2.创建应用对象 const app = express(); //3.创建路由规则 //requset是对请求报文的封装 //response是对相应报文的封装 app.get('/server', (request, response)=>{ // 设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin','*') //名字,值 // 设置响应体 response.send('HELLO AJAX GET') }); // all可以接受任意类型的请求 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: 'HELLO AJAX JSON2' } //对对象进行字符串转换 let str = JSON.stringify(data) // 设置响应体 response.send(str) }); // 针对 IE 缓存 app.get('/ie', (request, response)=>{ // 设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin','*') //名字,值 // 设置响应体 response.send('HELLO AJAX IE') }); // 延时响应 app.get('/delay', (request, response)=>{ // 设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin','*') //名字,值 setTimeout(() => { // 设置响应体 response.send('HELLO AJAX 延时响应') },3000) }); //4.监听端口启动服务 app.listen(8000, ()=>{ console.log("服务已经启动,8000 端口监听中..."); })
- 创建 5-超时与网络异常.html 文件
<!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: 100px; border:solid 1px #90b; } </style> </head> <body> <button>点击发送请求</button> <div id="result"></div> <script> const btn = document.getElementsByTagName('button')[0] const result = document.querySelector('#result') btn.addEventListener('click',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>
取消请求
需求:点击发送按钮,发送请求。点击取消按钮,瞬间取消请求。从而实现手动取消请求。
- server.js 文件不做变动
- 创建 6-取消请求.html 文件
<!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() } // abort方法 btns[1].onclick = function(){ x.abort() } </script> </body> </html>
abort()方法:可以停止一个XMLHttpRequest对象对HTTP的请求,把该对象恢复到初始状态。例如,如果某个操作需要一系列的操作顺序完成,而这其中出现任何异常,都会导致当前操作的结束,当检测到某个步骤出现异常时,使用abort()方法,中止当前的处理。
重复请求问题
问题:为避免用户重复发送同一个请求,从而给服务器带来巨大压力。可以在 6-取消请求.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 //是否正在发送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 } } } // abort方法 btns[1].onclick = function(){ x.abort() } </script> </body> </html>
不积跬步无以至千里 不积小流无以成江海