AJAX
一.原生 AJAX
1.1 AJAX 简介
-
AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML。
-
通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。
-
AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
1.2 XML 简介
-
XML 可扩展标记语言。
-
XML 被设计用来传输和存储数据。
-
XML 和 HTML 类似,不同的是 HTML 中都是预定义标签,而 XML 中没有预定义标签,
1.3 AJAX 的特点
1.3.1 AJAX 的优点
-
可以无需刷新页面而与服务器端进行通信。
-
允许你根据用户事件来更新部分页面内容。
1.3.2 AJAX 的缺点
-
没有浏览历史,不能回退
-
存在跨域问题(同源)
-
SEO 不友好
1.4 AJAX 的使用
引言
先了解一下express框架
1.安装express
在根目录下打开终端
2.命令行:
npm init --yes
npm i express
// 1.引入express const express = require('express') // 2.创建应用对象 const app = express() // 3.创建路由规则 // request是对请求报文的封装 // response是对响应报文的封装 app.get('/', (request, response) => { //设置响应 response.send('HELLO EXPRESS') }) // 4.监听端口启动服务器 app.listen(8000, () => { console.log('服务器已经启动,8000端口服务器监听中......'); })
在js文件的上一级文件在终端打开:‘node express.js'
注:此时8000端口号已经被占用,如果需要打开其他占用8000端口号的js文件,需要把这个文件关掉
1.4.1 核心对象
XMLHttpRequest,AJAX 的所有操作都是通过该对象进行的。
1.4.2 使用步骤
1.创建 XMLHttpRequest 对象
2.设置请求信息
3.发送请求
4.接收响应
1.4.3 解决 IE 缓存问题
问题:在一些浏览器中(IE),由于缓存机制的存在,ajax 只会发送的第一次请求,剩余多次请求不会在发送给浏览器而是直接加载缓存中的数据。
解决方式:浏览器的缓存是根据 url 地址来记录的,所以我们只需要修改 url 地址即可避免缓存问题
xhr.open("GET","/ie?t="+Date.now());
1.4.4 AJAX 请求状态
xhr.readyState 可以用来查看请求当前的状态
0: 表示 XMLHttpRequest 实例已经生成,但是 open()方法还没有被调用。
1: 表示 send()方法还没有被调用,仍然可以使用 setRequestHeader(),设定 HTTP 请求的头信息。
2: 表示 send()方法已经执行,并且头信息和状态码已经收到。
3: 表示正在接收服务器传来的 body 部分的数据。
4: 表示服务器数据已经完全接收,或者本次接收已经失败了
二.AJAX常用案例
引言
<!-- ##请求报文 --> <!-- 重点是格式与参数 --> 行 :请求类型+URL路径+http协议的版本(1.1) 头:名字:值 空行 体:GET的话:空 POST:可以不为空 <!-- ##响应报文 --> 行:HTTP/1.1 响应状态码 状态字符串 <!-- 响应状态码:404找不到 403被禁止 401未授权 500内部错误 200 OK --> 头:与请求报文相似 空行 体:html标签
2.1 AJAX案例准备
// 1.引入express const express = require('express') // 2.创建应用对象 const app = express() // 3.创建路由规则 // request是对请求报文的封装 // response是对响应报文的封装 app.get('/server', (request, response) => { //'/server'的含义是如果url请求行的第二段内容的路径是/server,这时执行后面回调函数,并且由response做出响应 //设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin', '*') //设置响应 response.send('HELLO ajax') }) app.post('/server', (request, response) => { //'/server'的含义是如果url请求行的第二段内容的路径是/server,这时执行后面回调函数,并且由response做出响应 //设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin', '*') //设置响应 response.send('HELLO ajax POST') }) // 4.监听端口启动服务器 app.listen(8000, () => { console.log('服务器已经启动,8000端口服务器监听中......'); })
在终端用nodemon.cmd运行此js文件
2.2 GET 请求
GET案例:
<body> <button>发送请求</button> <div id="result"></div> <script> const btn = document.querySelector('button') const result = document.getElementById('result') btn.addEventListener('click', function () { //1.创建对象 const xhr = new XMLHttpRequest() //2.初始化 设置请求的方法和URL 第一个参数是发送什么类型的请求,第二个参数是给谁发 xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&&b=200&c=300')//用问号分割,加名字的参数与值,有多个参数用&分割 //3.发送 xhr.send() //4.事件绑定 处理服务端返回的结果 // on when当什么的时候 // 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)//响应体 //设置result的文本 result.innerHTML = xhr.response } } } }) </script> </body>
2.3 POST 请求
POST 案例:
<body> <div id="result"></div> <script> const result = document.getElementById('result') result.addEventListener('mouseenter', function () { //1.创建对象 const xhr = new XMLHttpRequest() //2.初始化 设置类型与URL xhr.open('POST', 'http://127.0.0.1:8000/server') //3.发送 xhr.send('a=100&&b=200&c=300')//可以传递参数,在控制台server里的负载可以查看 //4.事件绑定 xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status >= 200 && xhr.status < 300) { result.innerHTML = xhr.response } } } }) </script> </body>
2.4设置请求头
在post.html文件里
//设置请求头 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') //Content-Type设置请求体内容的类型 application/x-www-form-urlencoded是参数查询字符串的类型(固定写法)
除此之外,还可以自定义
//其他类型的头信息 xhr.setRequestHeader('name', 'aheng')
注:在server.js文件里需要将app.post方法更改如下:
app.all('/server', (request, response) => { //'/server'的含义是如果url请求行的第二段内容的路径是/server,这时执行后面回调函数,并且由response做出响应 //设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin', '*') //响应头 response.setHeader('Access-Control-Allow-Headers', '*') //设置响应 response.send('HELLO ajax POST') })
并且重新在终端运行后,在浏览器打开
2.5服务端响应JSON数据
在server.html文件里
app.all('/json-server', (request, response) => { //'/server'的含义是如果url请求行的第二段内容的路径是/server,这时执行后面回调函数,并且由response做出响应 //设置响应头 设置允许跨域 response.setHeader('Access-Control-Allow-Origin', '*') //响应头 response.setHeader('Access-Control-Allow-Headers', '*') // 响应一个数据 const data = { uname: 'aheng' } //对对象进行字符串转换 let str = JSON.stringify(data) //设置响应 response.send(data) })
在JSON.js文件里
<body> <div id="result"></div> <script> const result = document.getElementById('result') window.addEventListener('keydown', 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) { //1.手动对数据进行转化 // let data = JSON.parse(xhr.response) // result.innerHTML = data.uname //2.自动转换 // xhr.responseType = 'json' } } } }) </script> </body>
重新启动server.js后,打开浏览器,按下键盘
2.6网络请求超时与网络异常
<body> <button>发送请求</button> <div id="result"></div> <script> const btn = document.querySelector('button') const result = document.getElementById('result') btn.addEventListener('click', function () { const xhr = new XMLHttpRequest() // 超时设置 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>
效果如下:
2.7请求取消
点击按钮手动取消请求
<body> <button class="one">点击发送</button> <button class="two">点击取消</button> <script> const btn1 = document.querySelector('.one') const btn2 = document.querySelector('.two') let xhr = null btn1.addEventListener('click', function () { xhr = new XMLHttpRequest() xhr.open('GET', 'http://127.0.0.1:8000/delay') xhr.send() }) //调用abort方法 btn2.addEventListener('click', function () { xhr.abort() }) </script> </body>
效果如下:
2.8重复请求问题
<body> <button class="one">点击发送</button> <script> const btn1 = document.querySelector('.one') let xhr = null // 标识变量 let isSending = false btn1.addEventListener('click', 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) { isSending = false } } }) </script> </body>
效果如下:
JSON基础
1.什么是JSON
-
JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式,目前使用特别广泛。
-
采用完全独立于编程语言的文本格式来存储和表示数据。
-
简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
-
易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
在 JavaScript 语言中,一切都是对象。因此,任何JavaScript 支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。看看他的要求和语法格式:
-
对象表示为键值对,数据由逗号分隔
-
花括号保存对象
-
方括号保存数组
2.JSON 键值对
JSON 键值对是用来保存 JavaScript 对象的一种方式,和 JavaScript 对象的写法也大同小异,键/值对组合中的键名写在前面并用双引号 "" 包裹,使用冒号 : 分隔,然后紧接着值:
{"name": "aheng"} {"age": "3"} {"sex": "nv"}
3.JSON本质
JSON 是 JavaScript 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
let obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的 let json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串
4.JSON 和 JavaScript 对象互转
JSON字符串转换为JavaScript 对象,使用 JSON.parse() 方法:
let obj = JSON.parse('{"a": "Hello", "b": "World"}'); //结果是 {a: 'Hello', b: 'World'}
JavaScript 对象转换为JSON字符串,使用 JSON.stringify() 方法:
let json = JSON.stringify({a: 'Hello', b: 'World'}); //结果是 '{"a": "Hello", "b": "World"}'
接口文档编写规范
API规范
(api 主要包括四部分:uri、请求方式、请求参数、返回参数,一般对这四部分做统一规范)
1.接口url:
是否是rest风格的,统一标识,比如登录的url: /login、比如查询列表以/list 结尾等
2.请求方式: GET 或者 POST
3.请求参数
参数名称 | 参数类型 | 说明 | 是否必填 |
---|---|---|---|
account | string | 账号 | 是 |
password | string | 密码 | 是 |
4.返回参数
{ "success": true, "code": 200, "msg": "success", "data": "token" }
接口返回结果 统一的数据结构:
HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 { "data": {}, "status": 0, "message": "给用户的提示信息" }
对返回的结果进行规定:都要包含数据data、状态码status、提示信息message 这三个字段,并且对状态码的值进行规定
/* 接口返回结果-封装到Result类中 */ public class Result { private boolean success; private int code; private String msg; private Object data; //成功、失败 返回的方法 public static Result success(Object data){ return new Result(true,200,"success",data); } public static Result fail(int code, String msg){ return new Result(false,code,msg, null); } }