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 = false btn.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 = false console.log(xhr.response) } } } } </script> </body>
16. jQuery 发送 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="https://cdn.bootcdn.net/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({ // 请求的url url: '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 发送请求
在后端服务器设置了跨域,在前端页面依旧显示跨域问题,在前端请求中设置请求头:
//请求头参数 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="https://cdn.bootcdn.net/ajax/libs/axios/0.19.2/axios.js"></script> <!-- 通过cdn引入 --> <script src="https://cdn.bootcss.com/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') //配置 baseURL axios.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', //url url: '/', //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> //文档地址 //https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetch const 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跨域请求 – 诗渊
【https://blog.csdn.net/u014607184/article/details/52027879】