根据视频进行整理
【/video/BV1WC4y1b78y?p=1】
视频资料
百度网盘:
链接:【/s/1nYiBc4hKzs8sYvAT5BZEZw】
提取码:1234
文章目录
1. AJAX 简介2. XML 简介3. AJAX 的特点3.1 AJAX 的优点3.2 AJAX 的缺点4. HTTP 协议4.1 请求报文4.2 响应报文4.3 浏览器中查看请求信息5. Node.js6. Express7. 发送GET请求7.1 GET请求设置参数8. 发送POST请求8.1 POST设置请求体8.2 设置请求头9. 服务端响应JSON格式的数据9.1 服务端返回的JSON自动转化10. nodemon11. 解决 IE 缓存问题12. 请求超时13. 网络异常14. 放弃请求15. 重复发送请求问题16. jQuery 发送 AJAX 请求17. axios 发送请求18. fetch 发送请求19. 跨域 -- cors19.1 cors19.2 CORS 的使用19.3 jsonp
1. AJAX 简介
AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。
通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。
AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
2. XML 简介
XML 可扩展标记语言。
XML 被设计用来传输和存储数据。在早期,AJAX使用XML进行数据传输,现在被JSON取代。
XML 和 HTML 类似,不同的是 HTML 中都是预定义标签(官方提前制定好的),而 XML 中没有预定义标签, 全都是自定义标签,用来表示一些数据。
比如,有一个学生数据:
name = "孙悟空" ; age = 18 ; gender = "男" ;
用 XML 表示:
<student> <name>孙悟空</name> <age>18</age> <gender>男</gender> </student>
用 JSON 表示:
{"name":"孙悟空","age":18,"gender":"男"}
3. AJAX 的特点
3.1 AJAX 的优点
可以无需刷新页面而与服务器端进行通信。允许你根据用户事件来更新部分页面内容(局部刷新、动态加载)。3.2 AJAX 的缺点
没有浏览历史,不能回退存在跨域问题(同源) (向请求数据就为跨域,AJAX默认是不允许的)SEO 不友好(由于使用AJAX动态加载数据,所以动态加载的数据在最初的页面html中不存在,不利于爬虫爬取数据)4. HTTP 协议
HTTP(hypertext transport protocol)协议:
超文本传输协议,详细规定了浏览器和万维网服务器之间互相通信的规则。就是浏览器和服务器之间进行通讯的一种约定和规则。
HTTP协议:
通过浏览器向服务器发生请求报文和服务器向浏览器返回响应报文的方式,进行浏览器和服务器之间的通讯和数据传输。
4.1 请求报文
请求报文包括:
请求行:
包括: 请求类型:GET/POST/PUT/DELETE/…url路径:/s?ie=utf-8http协议的版本:HTTP/1.1 (常用版本为1.1) 请求头:
包含的信息都为键值对
Host:
Cookie: name=guigu
Content-type: application/x-www-form-urlencoded
User-Agent: chrome 83空行请求体:
向服务器发送的信息(可以为空)
4.2 响应报文
响应报文包括:
响应行: http协议的版本:HTTP/1.1响应状态码:200/404/403/401…响应状态字符串: OK/… 响应头:
包含的信息都为键值对
Content-Type: text/html;charset=utf-8
Content-length: 2048
Content-encoding: gzip空行响应体 :
服务器响应给浏览器的数据
4.3 浏览器中查看请求信息
鼠标右键 => 检查F12笔记本 Fn => F125. Node.js
【Node.js----Node.js概述与安装和运行】
在Node.js环境下运行js文件(一定要在文件对应的位置运行)
node js文件名
6. Express
【Express】
AJAX阶段只是需要一个简单的服务器端进行请求的响应,只要能够创建一个基本的服务器即可
// 导入expressconst express = require('express')// 创建应用对象const app = express()// 创建路由对象// request 是对请求报文的封装// response 是对响应报文的封装app.get('/', (request, response) => {// 向客户端发送数据response.send( 'Hello from express' )})// 启动服务器进行监听// 8000 端口 服务端在8000端口监听客户端向8000端口发送过来的请求app.listen(8000, () => {console.log('服务端在8000端口监听')} )
app.get('/server', (request, response) => {//设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');...});
7. 发送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>Document</title><style>#result {width: 200px;height: 100px;border: solid 1px #90b;}</style></head><body><button>发送GET请求</button><div id="result"></div><script>// 获取按钮const btn = document.querySelector('button')// 获取divconst div = document.querySelector('div')// 绑定事件btn.addEventListener( 'click', function() {// 创建发送AJAX请求的对象const xhr = new XMLHttpRequest()// 初始化// 设置请求的方法和urlxhr.open( 'GET', 'http://127.0.0.1:8000/' )// 发送请求xhr.send()// 处理返回的数据// on 当...时候// readystate xhr 对象中的属性, 表示状态 0(未初始化的状态) 1(open方法调用完毕) 2(send方法调用完毕) 3(服务端返回部分结果) 4(服务端返回全部结果)// change 改变// 当状态改变会触发xhr.onreadystatechange = function() {// 服务端返回了所有的结果if ( xhr.readyState===4 ) {// 响应状态码 2xx 为成功if ( xhr.status>=200 && xhr.status<300 ) {// 返回的响应状态码console.log(xhr.status)// 返回的响应状态字符串console.log(xhr.statusText)// 返回的所有响应头console.log(xhr.getAllResponseHeaders)// 响应体(返回的数据)console.log(xhr.response)// 设置div中的文本div.innerHTML = xhr.response}}}} )</script></body></html>
7.1 GET请求设置参数
在请求地址url后加上?
,后面再加上参数名=参数值&参数名=参数值&...
,&为参数之间分隔
// 绑定事件btn.addEventListener( 'click', function() {// 创建发送AJAX请求的对象const xhr = new XMLHttpRequest()// 初始化// 设置请求的方法和urlxhr.open( 'GET', 'http://127.0.0.1:8000/?name=zs&age=18' )...})
edge浏览器
8. 发送POST请求
服务端:
// 导入expressconst express = require('express')// 创建应用对象const app = express()// 创建路由对象// request 是对请求报文的封装// response 是对响应报文的封装app.get('/', (request, response) => {//设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 向客户端发送数据response.send('Hello AJAX')})app.post('/', (request, response) => {//设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 向客户端发送数据response.send('Hello AJAX POST')})// 启动服务器进行监听// 8000 端口 服务端在8000端口监听客户端向8000端口发送过来的请求app.listen(8000, () => {console.log('服务端在8000端口监听')})
<!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>Document</title><style>#result {width: 200px;height: 100px;border: solid 1px #90b;}</style></head><body><button>发送POST请求</button><div id="result"></div><script>// 获取按钮const btn = document.querySelector('button')// 获取divconst div = document.querySelector('div')// 绑定事件btn.addEventListener('click', function () {// 创建发送AJAX请求的对象const xhr = new XMLHttpRequest()// 初始化 设置请求的方法和urlxhr.open('POST', 'http://127.0.0.1:8000/')// 发送请求xhr.send()// 处理返回的数据xhr.onreadystatechange = function () {// 服务端返回了所有的结果if (xhr.readyState === 4) {// 响应状态码 2xx 为成功if (xhr.status >= 200 && xhr.status < 300) {// 设置div中的文本div.innerHTML = xhr.response}}}})</script></body></html>
8.1 POST设置请求体
在xhr.send()中设置,可以设置任意类型任意格式的数据
// 绑定事件btn.addEventListener('click', function () {// 创建发送AJAX请求的对象const xhr = new XMLHttpRequest()// 初始化 设置请求的方法和urlxhr.open('POST', 'http://127.0.0.1:8000/')// 发送请求xhr.send('name=zs&age=12')...})
8.2 设置请求头
在open方法后进行添加 xhr.setRequestHeader()进行设置
// 绑定事件btn.addEventListener('click', function () {// 创建发送AJAX请求的对象const xhr = new XMLHttpRequest()// 初始化 设置请求的方法和urlxhr.open('POST', 'http://127.0.0.1:8000/')//设置请求头xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')// 发送请求xhr.send('name=zs&age=12')...})
9. 服务端响应JSON格式的数据
// 导入expressconst express = require('express')// 创建应用对象const app = express()// 创建路由对象// request 是对请求报文的封装// response 是对响应报文的封装app.get('/', (request, response) => {//设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 向客户端发送数据response.send('Hello AJAX')})app.post('/', (request, response) => {//设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 向客户端发送数据response.send('Hello AJAX POST')})app.get('/json', (request, response) => {//设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');const data = {name: 'zs',age: 12}// 对对象进行字符串转换let str = JSON.stringify(data)// 向客户端发送数据response.send(str)})// 启动服务器进行监听// 8000 端口 服务端在8000端口监听客户端向8000端口发送过来的请求app.listen(8000, () => {console.log('服务端在8000端口监听')})
<!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>Document</title><style>#result {width: 200px;height: 100px;border: solid 1px #90b;}</style></head><body><button>发送GET请求JSON数据</button><div id="result"></div><script>// 获取按钮const btn = document.querySelector('button')// 获取divconst div = document.querySelector('div')// 绑定事件btn.addEventListener('click', function () {// 创建发送AJAX请求的对象const xhr = new XMLHttpRequest()// 初始化 设置请求的方法和urlxhr.open('GET', 'http://127.0.0.1:8000/json')// 发送请求xhr.send()// 处理返回的数据xhr.onreadystatechange = function () {// 服务端返回了所有的结果if (xhr.readyState === 4) {// 响应状态码 2xx 为成功if (xhr.status >= 200 && xhr.status < 300) {// 设置div中的文本div.innerHTML = xhr.responseconsole.log(xhr.response)// 手动对数据进行转化console.log(JSON.parse(xhr.response))}}}})</script></body></html>
9.1 服务端返回的JSON自动转化
设置:
// 设置响应体数据的类型xhr.responseType = '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>Document</title><style>#result {width: 200px;height: 100px;border: solid 1px #90b;}</style></head><body><button>发送GET请求JSON数据</button><div id="result"></div><script>// 获取按钮const btn = document.querySelector('button')// 获取divconst div = document.querySelector('div')// 绑定事件btn.addEventListener('click', function () {// 创建发送AJAX请求的对象const xhr = new XMLHttpRequest()// 设置响应体数据的类型xhr.responseType = 'json'// 初始化 设置请求的方法和urlxhr.open('GET', 'http://127.0.0.1:8000/json')// 发送请求xhr.send()// 处理返回的数据xhr.onreadystatechange = function () {// 服务端返回了所有的结果if (xhr.readyState === 4) {// 响应状态码 2xx 为成功if (xhr.status >= 200 && xhr.status < 300) {// 设置div中的文本div.innerHTML = xhr.responseconsole.log(xhr.response)// 手动对数据进行转化// console.log(JSON.parse(xhr.response))}}}})</script></body></html>
10. nodemon
【Express】
11. 解决 IE 缓存问题
在一些浏览器中(IE),由于缓存机制的存在,ajax 只会发送的第一次请求,剩 余多次请求不会在发送给浏览器而是直接加载缓存中的数据。
解决方式:
浏览器的缓存是根据 url 地址来记录的,所以我们只需要修改 url 地址 即可避免缓存问题。
在请求url后添加?t='+Date.now()
将原来的请求地址:
xhr.open( 'GET', 'http://127.0.0.1:8000/ie' )
修改为:
xhr.open("GET",'http://127.0.0.1:8000/ie?t='+Date.now());
由于每次的请求时间不一样,产生的时间戳不一样,所以每次发起的请求url都不同。
<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>
12. 请求超时
请求超时设置:
//超时设置 2s,当请求的时间超过两秒时视为网络请求超时xhr.timeout = 2000;//超时回调,当请求超时时要执行的代码xhr.ontimeout = function(){alert("网络异常, 请稍后重试!!");}
服务端代码:
app.get('/delay', (request, response) => {//设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');setTimeout(() => {// 向客户端发送数据response.send("HELLO AJAX")}, 3000)})
页面:
<style>#result {width: 200px;height: 100px;border: solid 1px #90b;}</style>
<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.timeout = 2000 // 请求时间超过两秒时则为超时xhr.ontimeout = function(){console.log('请求超时....')}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>
当请求超时时,会自动放弃本次的请求
13. 网络异常
网络异常设置:
//网络异常回调,当网络异常时执行下面的回调xhr.onerror = function(){alert("你的网络似乎出了一些问题!");}
服务端代码:
app.get('/error', (request, response) => {//设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');setTimeout(() => {// 向客户端发送数据response.send("HELLO AJAX")}, 3000)})
网页:
<style>#result {width: 200px;height: 100px;border: solid 1px #90b;}</style>
<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.onerror = function(){console.log('网络出现了问题.....')}xhr.open( 'GET', 'http://127.0.0.1:8000/error' )xhr.send()xhr.onreadystatechange = function() {if ( xhr.readyState===4 ) {if ( xhr.status>=200 && xhr.status<300 ) {result.innerHTML = xhr.response}}}})</script></body>
14. 放弃请求
使用 abort() 方法放弃请求
<body><button>点击发送</button><button>点击取消</button><script>const btns = document.querySelectorAll('button')const xhr = new XMLHttpRequest()btns[0].onclick = function() {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 ) {console.log(xhr.response)}}}}btns[1].onclick = function() {xhr.abort()}</script></body>
15. 重复发送请求问题
重复频繁的发送同一个请求会对服务端照常压力。
当前已经发送了请求,再次发送请求时,取消前一次的请求。
<body><button>点击发送</button><script>//获取元素对象const btn = document.querySelector('button')let xhr = null// 设置一个标识,是否正在发送请求let isSending = falsebtn.onclick = function () {// 如果正在发送请求,取消前面的请求if( isSending ) xhr.abort()xhr = new XMLHttpRequest()isSending = true // 正在发送请求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) {// 请求回来后isSending = falseconsole.log(xhr.response)}}}}</script></body>
16. jQuery 发送 AJAX 请求
【AJAX中文文档】
<!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>Document</title><script src="/ajax/libs/jquery/3.5.1/jquery.min.js"></script></head><body><button>发送GET</button><button>发送POST</button><button>通用方法发送请求</button><script>// eq()选择第几个元素$('button').eq(0).click(function () {// 第一个参数,请求的地址// 第二个参数,请求携带的参数// 第三个参数,请求回来的回调函数$.get('http://127.0.0.1:8000', {a: 100, b: 200 }, function (data) {console.log(data)})})$('button').eq(1).click(function () {// 第一个参数,请求的地址// 第二个参数,请求携带的参数// 第三个参数,请求回来的回调函数$.post('http://127.0.0.1:8000', {a: 100, b: 200 }, function (data) {console.log(data)})})$('button').eq(2).click(function(){// 参数为一个对象$.ajax({// 请求的urlurl: 'http://127.0.0.1:8000/json',// 请求携带的参数data: {a: 100, b: 200},// 请求的方式type: 'GET',// 设置响应体的数据形式dataType: 'json',// 设置成功的回调函数success: function(data) {console.log(data)},// 设置超时时间// 超时会执行error的回调timeout: 2000,// 失败的回调error: function() {console.log('ERROR')},// 设置请求的头信息// headers: {// c: 300,// d: 400// }})})</script></body></html>
17. axios 发送请求
【axios github仓库地址】
在后端服务器设置了跨域,在前端页面依旧显示跨域问题,在前端请求中设置请求头:
//请求头参数headers: {'Content-Type': 'application/x-www-form-urlencoded'}
因为大多数服务器只能识别请求头 Content-Type 为 application/x-www-form-urlencodedaxios 的请求,而 axios 的 Content-Type 是 application/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>Document</title><script crossorigin="anonymous" src="/ajax/libs/axios/0.19.2/axios.js"></script><!-- 通过cdn引入 --><script src="/qs/6.9.0/qs.min.js"></script></head><body><button>GET</button><button>POST</button><button>AJAX</button><script>const btns = document.querySelectorAll('button')//配置 baseURLaxios.defaults.baseURL = 'http://127.0.0.1:8000'btns[0].onclick = function () {// 返回的为promise对象// 第一个参数为请求地址// 第二个参数为配置信息axios.get('/', {// 参数params: {name: 'zs',age: 12,},//请求头参数headers: {'Content-Type': 'application/x-www-form-urlencoded',},}).then((response) => {console.log(response)})}btns[1].onclick = function () {// 第一个参数请求地址// 第二个参数为请求携带参数// 第三个参数为配置信息axios.post('/',{name: 'zs',age: 12,},{params: {a: 100,b: 200,},//请求头参数headers: {'Content-Type': 'application/x-www-form-urlencoded',},}).then((response) => {console.log(response)})}btns[2].onclick = function () {axios({//请求方法method: 'POST',//urlurl: '/',//url参数params: {vip: 10,level: 30,},//头信息headers: {'Content-Type': 'application/x-www-form-urlencoded',},//请求体参数data: {username: 'admin',password: 'admin',},}).then((response) => {//响应状态码console.log(response.status)//响应状态字符串console.log(response.statusText)//响应头信息console.log(response.headers)//响应体console.log(response.data)})}</script></body></html>
18. fetch 发送请求
【文档地址】
<!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>Document</title></head><body><button>AJAX请求</button><script>//文档地址///zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetchconst btn = document.querySelector('button')btn.onclick = function () {fetch('http://127.0.0.1:8000/', {//请求方法method: 'POST',//请求头headers: {'Content-Type': 'application/x-www-form-urlencoded'},//请求体body: 'username=admin&password=admin',}).then((response) => {return response.text()// return response.json()}).then((response) => {console.log(response)})}</script></body></html>
19. 跨域 – cors
【文档】
19.1 cors
CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持 get 和 post 请求。跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些 源站通过浏览器有权限访问哪些资源
CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应 以后就会对响应放行。
19.2 CORS 的使用
主要是服务器端的设置:
// 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*');// 设置响应头response.setHeader('Access-Control-Allow-Headers', '*');// 设置允许请求的方法response.setHeader('Access-Control-Allow-Methods', '*');...
在后端服务器设置了跨域,在前端页面依旧显示跨域问题,在前端请求中设置请求头:
//请求头参数headers: {'Content-Type': 'application/x-www-form-urlencoded'}
因为大多数服务器只能识别请求头 Content-Type 为 application/x-www-form-urlencodedaxios 的请求,而 有的请求的 Content-Type 是 application/json
【解决方法博客】
19.3 jsonp
轻松搞定JSONP跨域请求 – 诗渊
【/u014607184/article/details/52027879】
如果觉得《AJAX(GET POST请求 jQuery axios 发送请求 跨域--cors 请求超时 网络异常 放弃请求 重复发送请求)》对你有帮助,请点赞、收藏,并留下你的观点哦!