Ajax
- 概念:Asynchronous JavaScript And XML,异步的 JavaScript 和XML
- 作用:
- 数据交换:通过Ajx可以给服务器发送请求,并获取服务器响应的数据。
- 异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用的校验等等。
- 缺点:
- 没有浏览历史,不能回退
- 存在跨域问题(同源)
- SEO不友好(SEO:搜索引擎优化Search Engine Optimization),Ajax请求的数据爬虫爬不到,或者说源代码(响应体)中没有Ajax数据,Ajax数据是Js动态创建的
HTTP
HTTP ( Hypertext Transport Protocol ) 超文本传输协议,规定了浏览器和万维网服务器之间互相通信的规则
接下来重点介绍请求响应格式与参数
请求报文
浏览器向服务器发送请求
get请求:请求体是空的,
post请求:请求体可以为空
1 2 3 4
| 请求行 GET /URL路径 HTTP协议版本 请求头 Key: Value 空行 请求体 username=kenny
|
响应报文
服务器向浏览器响应请求
1 2 3 4
| 响应行 HTTP协议版本 响应状态码(200) 状态字符串(OK) 响应头 Key: Value 空行 响应体 <html>...</html>
|
Express框架
因为Ajax需要给服务端发请求,需要一个服务端
Express:基于Node.js平台,快速、开放、极简的Web开发框架
当然Java佬用SpringBoot也可以
安装Express框架
在项目目录下初始化npm包管理工具
安装Express
基本使用
express.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const express = require('express');
const app = express();
app.get('/', (request, response)=>{ response.send('HELLO EXPRESS'); });
app.listen(8000,()=>{ console.log("服务已经启动,8000端口监听中..."); })
|
在这个js文件目录启动终端,用node命令启动服务
可以在127.0.0.1:8000 查看
原生Ajax
GET示例:
需求:点击按钮给服务端发送数据,将服务端响应体结果呈现在div中
页面与服务器准备
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Ajax GET</title> <style> #result { width: 200px; height: 200px; border: solid 1px pink; } </style> </head> <body> <button>点击发送请求</button> <div id="result"></div> </body> </html>
|
服务器js代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const express = require('express');
const app = express();
app.get('/server', (request, response)=>{ response.setHeader('Access-Control-Allow-Origin', '*')
response.send('HELLO EXPRESS'); });
app.listen(8000,()=>{ console.log("服务已经启动,8000端口监听中..."); })
|
Ajax操作步骤
将服务端js代码改一改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const express = require('express');
const app = express();
app.get('/server', (request, response)=>{ response.setHeader('Access-Control-Allow-Origin', '*')
response.send('HELLO EXPRESS'); });
app.listen(8000,()=>{ console.log("服务已经启动,8000端口监听中..."); })
|
页面端html添加js代码
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
| <script> const btn = document.querySelector('button'); const result = document.querySelector('#result'); btn.addEventListener('click',()=>{ const xhr = new XMLHttpRequest() xhr.open('GET', 'http://127.0.0.1:8000/server') xhr.send() xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ if(xhr.status >= 200 && xhr.status< 300){ console.log(xhr.status); console.log(xhr.statusText); console.log(xhr.getAllResponseHeaders()); console.log(xhr.response);
result.innerHTML = xhr.response }else{
} } } }) </script>
|
步骤:
- 创建XMLHttpRequest对象:用于和服务器交换数据
- 向服务器发送请求
- 获取服务器响应数据
示例:
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
| <!DOCTYPE html> <html> <body>
<div id="demo"> <h2>The XMLHttpRequest Object</h2> <button type="button" onclick="loadDoc()">Change Content</button> </div>
<script> function loadDoc() { const xhttp = new XMLHttpRequest(); xhttp.onload = function() { document.getElementById("demo").innerHTML = this.responseText; } xhttp.open("GET", "https://www.w3schools.com/js/ajax_info.txt"); xhttp.send(); } </script>
</body> </html>
|
GET参数
1
| xhr.open('GET', 'url?a=100')
|
POST示例
需求,把鼠标放到div上的时候,向服务器发送POST请求,将响应的结果放回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
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Ajax POST</title> <style> #result { width: 200px; height: 200px; border: solid 1px red; } </style> </head> <body> <div id="result"></div> <script> const result = document.querySelector('#result'); result.addEventListener('mouseover',()=>{ const xhr = new XMLHttpRequest() xhr.open('POST', 'http://127.0.0.1:8000/server') xhr.send() xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ if(xhr.status >= 200 && xhr.status< 300){ result.innerHTML = xhr.response }else{
} } } }) </script> </body> </html>
|
服务端
1 2 3 4 5 6 7
| app.post('/server', (request, response)=>{ response.setHeader('Access-Control-Allow-Origin', '*')
response.send('HELLO EXPRESS POST'); });
|
POST参数
在send里面设置
1 2
| xhr.send('a=100?b=200')
|
理论上请求体内容可以随便写,只要服务端能处理相关格式的数据就可以
请求头设置
比如
1
| xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
|
Content-Type:设置请求体内容类型。 后面那一长串是参数查询字符串的固定写法
不用记
前面的是预定义请求头,还可以自定义
自定义请求头
1
| xhr.setRequestHeader('name','kenny')
|
请求报文的自定义头一般由后端人员设置,并且需要在服务端允许自定义响应头
1 2
| response.setHeader('Access-Control-Allow-Headers', '*')
|
响应Json数据
示例
需求:在窗口内任意位置按下键盘按键,发起请求并相应服务器的Json数据
页面html代码
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
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Ajax Json</title> <style> #result { height: 200px; width: 200px; border: solid 1px pink; } </style> </head> <body> <div id="result"></div>
<script> const result = document.querySelector('#result') window.addEventListener('keydown', ()=>{ 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);
console.log(xhr.response); result.innerHTML = xhr.response.name } } } }) </script> </body> </html>
|
服务端js
1 2 3 4 5 6 7 8 9 10 11 12
| app.get('/json-server', (request, response)=>{ response.setHeader('Access-Control-Allow-Origin', '*')
const data = { name: 'Kenny' } let str = JSON.stringify(data) response.send(str); });
|
XMLHttpRequest 对象属性
Property |
Description |
onload |
定义接收(加载)请求时要调用的函数。 |
onreadystatechange |
定义当readyState 属性发生变化时被调用的函数 |
readyState |
保存 XMLHttpRequest 的状态 * 0: 请求未初始化 * 1: 服务器链接已建立 * 2: 请求已收到 * 3: 正在处理请求 * 4: 请求已完成且相应已建立 |
responseText |
Returns the response data as a string |
responseXML |
Returns the response data as XML data |
status |
返回请求的状态号 * 200: “OK” * 403: “Forbidden” * 404: “Not Found”
完整列表请访问 Http Messages Reference |
statusText |
返回状态文本 (e.g. “OK” or “Not Found”) |
所以为了确保请求成功
可以将代码写成这样
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| function loadDoc() { const xhttp = new XMLHttpRequest(); xhttp.onload = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("demo").innerHTML = this.responseText; } } xhttp.open("GET", "https://www.w3schools.com/js/ajax_info.txt"); xhttp.send(); }
|
Axios
原生Ajax比较繁琐,以及存在一些早期的浏览器兼容问题, 现在项目中一般使用原生Ajax封装的Axios
Axios入门
-
引入 Axios.js 文件
-
使用Axios发送请求,获取响应结果
示例:
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
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <title>Document</title> </head> <body> <input type="button" value="获取数据get" onclick="get()"> <input type="button" value="获取数据post" onclick="post()"> </body> <script> function get(){ axios({ method: 'get', url:'https://autumnfish.cn/api/joke' }).then( result =>{ console.log(result.data); }) }
function post(){ axios({ method: 'post', url:'https://autumnfish.cn/api/user/check', data: "username=name" }).then( result =>{ console.log(result.data); }) } </script>
</html>
|
Axios请求方式别名
更加快速的使用
别名:
- axios.get(url [config])
- axios.delete(url [config])
- axios.post(url [data[,config]])
- axios.put(url [data[,config]])
发送get请求:
1 2 3
| axios.get("https://autumnfish.cn/api/joke").then((result)=>{ console.log(result.data) })
|
发送post请求
1 2 3
| axios.post("https://autumnfish.cn/api/user/check","username=name").then((result)=>{ console.log(result.data) })
|
简化代码之后:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <script> function get(){ axios.get("https://autumnfish.cn/api/joke").then((result)=>{ console.log(result.data) }) }
function post(){ axios.post("https://autumnfish.cn/api/user/check","username=name").then((result)=>{ console.log(result.data) }) } </script>
|