前端AjaxAjax
定西Ajax
前言
学完SpringBoot,仔细了解了一下学习路线,还是要学vue啊,但是vue又用到了axios,而axios又用到了ajax
所以我来了
同样还是尚硅谷的视频,视频地址
Ajax基础
原生Ajax
Ajax简介
Ajax全程为Asynchronous JavaScript And XML 就是异步的JS和XML,通过Ajax可以在浏览器中向服务器发送异步请求,最大的优势,无刷新获取数据Ajax不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式
前面这两节课都是介绍场景,然后还有xml简介的,这个再熟悉不过了
Ajax的优缺点
优点
- 可以无需刷新页面与服务器端进行通信
- 允许你根据用户事件来更新部分页面内容
缺点
- 没有浏览历史,不能回退
- 存在跨域问题(同源)
- SEO不友好
HTTP协议
这老师怎么突然从word跑到了vscode的markdown了哈哈哈哈艹
请求报文
重点是格式与参数
响应报文
Node.js
竟然用到这个东西了,之前装这个东西还是在写博客的时候
没想到这么巧
就直接拿来用了
Express
这个是没听过
就是用于代替服务端的,毕竟学前端的人不会去学后端,我感觉我可以自己来写一下后端哎,反正是接收请求啥的
先跟着老师写,然后看看能不能自己改成controller啥的
安装也很简单
管理员模式:
- npm init –yes
- npm i express
就安装好了
express的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const { request, response } = require('express'); const express = require('express');
const app = express();
app.get('/',(request,response)=>{ response.send("Hello Express"); });
app.listen(8000, ()=>{ console.log("服务已经启动,8000 端口监听中"); });
|
简单案例
GET
先是服务端
跟上面的代码区别不大,主要区别就在于设置了一个响应头,用于允许跨域,以及设置get请求的请求路径为/server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const { request, response } = require('express'); const express = require('express');
const app = express();
app.get('/server',(request,response)=>{
response.setHeader('Access-Control-Allow-Origin','*')
response.send('HELLO AJAX') });
app.listen(8000, ()=>{ console.log("服务已经启动,8000 端口监听中"); });
|
然后是页面实现
还是基础的js语法,大概想起了一些,什么document
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| <!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> const btn = document.getElementsByTagName('button')[0]; const result = document.getElementById('result'); btn.onclick = function () { const xhr = new XMLHttpRequest(); xhr.open('GET', 'http://localhost:8000/server'); xhr.send(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) { result.innerHTML = xhr.responseText; }else{
} } }; } </script>
</body>
</html>
|
所以那个server.js,其实就是默认了一个服务器
直接用tomcat应该也一样,用SpringBoot创建一个项目,写一个controller接收server请求就行了
没问题啊没问题
看代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package com.zzmr.boot.controller;
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;
@RestController @CrossOrigin public class AjaxController {
@GetMapping("/server") public String replaceServer(){ return "Hello Ajax"; }
}
|
发送参数
直接在url后面拼接就行了
在SpringBoot允许跨域,其中的一个注解就是@CrossOrigin(刚百度的)
加上这个注解,就和写的server.js效果一样了
POST
案例简介:当鼠标放到div上时,向服务端发送请求,将响应体在div中展示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| <!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 #904; } </style> </head> <body> <div id="result"></div> <script> const result = document.getElementById("result"); result.addEventListener("mouseover", function() { const xhr = new XMLHttpRequest(); xhr.open("POST", 'http://localhost:8000/server') xhr.send('a:100&b:200&c=300'); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if(xhr.status >= 200 && xhr.status <300){ result.innerHTML = xhr.response; } } } }); </script> </body> </html>
|
也没什么难的
Ajax设置请求头
就是在open()后面再加一个方法
1 2 3 4 5
|
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.setRequestHeader('name','zzmr');
|
服务端响应Json格式数据
案例简介:在这个窗口下,按下任何一个按键,就会像服务端发送请求,服务端返回结果,把结果呈现在div中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| <!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 Json</title> <style> #result { width: 200px; height: 100px; border: solid 1px rgb(46, 203, 72); } </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://localhost:8000/json-server'); xhr.send(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) {
result.innerHTML = xhr.response.name; } } }; } </script> </body>
</html>
|
这里也很简单,主要就是注意前端接受后端发来的json格式的数据,如何转换的问题
有两种方式:
手动转换-调用JSON.parse()
1 2 3
| let data = JSON.parse(xhr.response); result.innerHTML = data.name;
|
自动转换
在新建xhr的时候设置
1 2
| xhr.responseType = 'json';
|
这样,就可以直接用了
1 2
| result.innerHTML = xhr.response.name;
|
这里我还是用的SpringBoot自己实现的服务端
1 2 3 4 5 6 7 8
| @GetMapping("/json-server") public Map replaceJsonServer() { Map<String, String> map = new HashMap<>(); map.put("name", "zzmr"); return map; }
|
nodemon
自动重启服务
安装命令:
npm install -g nodemon
开启服务的命令:
npx nodemon server.js
不加npx就报错..
但是我感觉我用不到啊
解决IE缓存问题
案例就不写了,知道是用什么手法解决的就行:
时间戳解决
请求路径:’http://localhost:8000/ie?t'+Date.now()
各类问题
超时与网路异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <script> const button = document.getElementsByTagName('button')[0]; const result = document.querySelector('#result');
button.addEventListener('click', function () { const xhr = new XMLHttpRequest();
xhr.timeout = 2000; xhr.ontimeout = function(){ alert("网络异常,请稍后重试"); } xhr.onerror = function(){ alert("网络似乎除了一些问题"); }
xhr.open('GET', "http://localhost:8000/timeout"); xhr.send(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) { result.innerHTML = xhr.response; } } } }) </script>
|
也没啥,就是两个方法:ontimeout和onerror
后端的话,用了sleep
1 2 3 4 5 6 7
| @GetMapping("/timeout") public String replaceTimeServer() throws InterruptedException {
Thread.sleep(3000); return "延时响应"; }
|
取消请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <script> const btn1 = document.getElementsByTagName('button')[0]; const btn2 = document.getElementsByTagName('button')[1]; let xhr = null;
btn1.onclick = function() { xhr = new XMLHttpRequest(); xhr.open('GET','http://localhost:8000/timeout'); xhr.send(); }
btn2.onclick = function() { xhr.abort(); } </script>
|
取消就是一个abort()方法,需要注意的是要把变量xhr声明在两个onclick方法外面(但是我实测在里面也一样能访问到)
请求重复发送
同一个请求,连续发送,会造成服务器压力过大的情况
原理就是,发送一个请求,先看一下之前是否有相同请求(该暂未响应),有的话,就取消上次的请求,发送新的请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <script> const btn1 = document.getElementsByTagName('button')[0]; const btn2 = document.getElementsByTagName('button')[1]; let xhr = null;
let isSending = false;
btn1.onclick = function () { if (isSending) { xhr.abort(); } xhr = new XMLHttpRequest(); isSending = true; xhr.open('GET', 'http://localhost:8000/timeout'); xhr.send(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { isSending = false; } } }
btn2.onclick = function () { xhr.abort(); } </script>
|
就是使用了一个标识变量,但是说实话我这我有一点迷
JQuery中的Ajax
GET请求和POST请求
1 2 3 4 5 6 7 8 9 10 11 12 13
| <script> $('button').eq(0).click(function () { $.get('http://localhost:8000/jquery-server', { a: 100, b: 200 }, function (data) { console.log(data); }); })
$('button').eq(1).click(function () { $.post('http://localhost:8000/jquery-server', { a: 100, b: 200 }, function (data) { console.log(data); }, 'json'); }) </script>
|
写了两个控制器方法
1 2 3 4 5 6 7 8 9 10 11
| @GetMapping("/jquery-server") public String JQueryGETServer(){ return "Hello JQuery Ajax -- GET"; }
@PostMapping("/jquery-server") public Map JQueryPOSTServer(){ Map<String, String> map = new HashMap<>(); map.put("name", "zzmr"); return map; }
|
通用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| $('button').eq(2).click(function () { $.ajax({ url: 'http://localhost:8000/jquery-server', data: { a: 100, b: 200 }, type: 'POST', dataType: 'json', success: function (data) { console.log(data); }, timeout: 2000, error: function () { console.log('出错了!!!!'); }, headers: { c:300, d:400 } }); });
|
axios
最热门的ajax工具库
项目地址
可以在目录里安装axios,也可以在页面引用:
1
| <script src="https://gcore.jsdelivr.net/npm/axios@1.1.2/dist/axios.min.js"></script>
|
使用cdn加速:
1
| <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/1.2.2/axios.js"></script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| <script> const btns = document.querySelectorAll('button');
btns[0].onclick = function () { axios.get('http://localhost:8000/axios-server', { params: { id: 100, vip: 7 }, headers: { name: 'zzmr', age: 20 }, }).then(value => { console.log(value); }); }
btns[1].onclick = function () { axios.post('http://localhost:8000/axios-server', { username: 'admin', password: 'admin' }, { params: { id: 200, vip: 9 }, headers: { height: 180, weight: 180, } }); }
btns[2].onclick = function () { axios({ method : 'POST', url: 'http://localhost:8000/axios-server', params: { vip:10, level:30 }, headers: { a:100, b:200 }, data: { username: 'admin', package: '010203' } }).then(response=>{ console.log(response); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.data); }) }
</script>
|
最下面的这种是最常用的
使用fetch函数发送Ajax请求
这个放着吧,不想看了
同源策略
一种安全策略
同源:协议,域名,端口号必须完全相同
违背同源策略就是跨域
看看吧,剩下的都是知识点,前面的都是讲怎么用的
<script>
标签默认可以实现跨域
jsonp
Jquery实现Jsonp
还有CORS
就仔细看看CORS吧
CORS:跨域资源共享,CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和post请求(还有其他的),跨域资源共享标准新增了一组HTTP首字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源
就是加上@CrossOrigin注解其实是
结束了
2022年12月31日 18点34分