目录
一、利用 JSON 字符串 返回数据
(一)基础代码
(二)原理及实现
二、nodmon 工具 自动重启服务
(一)用途
(二)下载
(三)使用
三、IE 缓存问题
(一)问题描述
(二)解决方法
三、AJAX 请求超时 / 网络异常处理
(一)处理方法
(二)完整代码
四、AJAX 取消请求
五、AJAX 请求重复发送问题
一、利用 JSON 字符串 返回数据
利用 AJAX 向服务端发送请求,服务端向我们返回的一般都是 JSON 格式的数据
在 div 中按键 向服务端发出请求 并在 div 中渲染返回结果
和前面类似不多解释了,不明白细节可以看上一篇
(一)基础代码
AJAX 前端代码:
<!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>
</head>
<style>#result {width: 200px;height: 100px;border: solid pink 1px;}
</style><body><div id="result"></div><script>// 获得元素对象const result = document.getElementById("result")// 绑定键盘按下事件window.onkeydown = function () {// 创建对象const xhr = new XMLHttpRequest();// 初始化设置请求方法 和url(就是发送的对象)xhr.open('GET', 'http://127.0.0.1:8000/json-server')// 设置请求头xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')// 自定义请求头xhr.setRequestHeader('name', 'hahaha')// 发送xhr.send('a=100&b=200')// 事件绑定 处理服务端返回的结果xhr.onreadystatechange = function () {// 在里面处理服务端返回的结果 在 4 时再处理if (xhr.readyState === 4) {// 判断响应的状态码 200 404 403 401 500// 2 开头都表示成功if (xhr.status >= 200 && xhr.status < 300) {result.innerHTML = xhr.response}}}}</script>
</body></html>
服务端代码:
// 1、先引入 express 框架
const express = require('express')
// 2、然后创建应用对象
const app = express()
// 3、创建路由规则,函数里面有两个参数,分别是请求报文和响应报文的封装
app.all('/json-server', (request, response) => {// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*')// 特殊响应头response.setHeader('Access-Control-Allow-Headers', '*')// 设置响应体response.send('HELLO AJAX POST')
})
// 4、监听端口启动服务
app.listen(8000, () => {console.log('服务已经启动,8000端口监听中...')
})
(二)原理及实现
我们想返回别的东西 不想只返回一堆字,比如说我们想返回一个对象 ,但是respond() 方法只能返回字符串,所以我们可以通过把 data 对象转换成 JSON 字符串的形式返回
const data = {name: '一个人'}let str = JSON.stringify(data)response.send(str)
结果展示:此时返回的是一个字符串
可以在前端代码中把字符串重新转换成对象
if (xhr.readyState === 4) {// 判断响应的状态码 200 404 403 401 500// 2 开头都表示成功if (xhr.status >= 200 && xhr.status < 300) {let data = JSON.parse(xhr.response)console.log(data)}}
输出检验一下,确实是对象
但是上面属于手动转换,我们可以自动转换
加上一句下面就可以自动转换了
xhr.responseType = 'json'
成功
在页面中显示数据 就稍微改一下渲染一下就行
结果展示:
二、nodmon 工具 自动重启服务
(一)用途
可以让我们修改服务端代码时不用重新启动服务器,节省时间
(二)下载
我们直接 在没有服务端启动的情况下 在终端界面 输入
npm install -g nodemon 就能下载了
(三)使用
然后我们以后启动服务器时用
nodemon.cmd 服务器文件名.js 就行了
三、IE 缓存问题
(一)问题描述
IE 浏览器会对 AJAX 的请求结果做一个缓存,下一次再发送请求时,走的是本地的缓存而不是服务器返回的最新的数据,对于时效性比较强的场景,AJAX 的缓存会影响结果
如果修改服务端传回的内容 在 ie 浏览器中刷新 显示内容不会发生改变,因为 ie 是从本地缓存中取出的数据
(二)解决方法
代码如下:在 open 方法代码中的 url 后面加上 当前时间戳 这样每次点击 ie 浏览器收到的请求都不一样,ie 以为我们发送了一个新的请求,这样就不会从本地缓存中读取数据了
xhr.open('GET', 'http://127.0.0.1:8000/ie?t='+Date.now())
三、AJAX 请求超时 / 网络异常处理
(一)处理方法
我们不能保证服务端一直准确快速响应 AJAX 请求,我们可以通过给 AJAX 加一个超时的设置,给用户提醒,网络异常的时候也给用户提醒,让产品体验更好
我们可以在服务器中设置一个延时函数 3秒后返回 延时响应
setTimeout(() =>{response.send('延时响应')},3000)
在 AJAX 中设置一些代码 如果 2s 内还没返回请求就取消
xhr.timeout = 2000
超时回调,就是超时弹出对话框
xhr.ontimeout = function (){alert('网络异常,稍后再试')}
(二)完整代码
AJAX部分:
<script>const btn = document.getElementsByTagName('button')[0]const result = document.getElementById("result")btn.addEventListener('click', function () {const xhr = new XMLHttpRequest();// 超时设置xhr.timeout = 2000// 超时回调xhr.ontimeout = function () {alert('网络异常,稍后再试')}xhr.onerror = function(){alert('你的网络似乎出现了问题')}// 初始化设置请求方法 和url(就是发送的对象)xhr.open('GET', 'http://127.0.0.1:8000/delay')// 发送xhr.send('')// 事件绑定 处理服务端返回的结果xhr.onreadystatechange = function () {// 在里面处理服务端返回的结果 在 4 时再处理if (xhr.readyState === 4) {// 判断响应的状态码 200 404 403 401 500// 2 开头都表示成功if (xhr.status >= 200 && xhr.status < 300) {result.innerHTML = xhr.response}}}})
</script>
服务端部分:
// 1、先引入 express 框架
const express = require('express')
// 2、然后创建应用对象
const app = express()
// 3、创建路由规则,函数里面有两个参数,分别是请求报文和响应报文的封装
app.all('/delay', (request, response) => {// 设置响应头 设置允许跨域response.setHeader('Access-Control-Allow-Origin', '*')// 特殊响应头response.setHeader('Access-Control-Allow-Headers', '*')// 设置响应体setTimeout(() => {response.send('hello ie')}, 3000)
})
// 4、监听端口启动服务
app.listen(8000, () => {console.log('服务已经启动,8000端口监听中...')
})
四、AJAX 取消请求
在我们通过 AJAX 向服务器发送请求时,在服务器返回数据前,我们可以通过代码手动取消请求
使用 abort 方法 属于 AJAX 对象
就如下面 使用 x.abort() 就能取消请求
注意下面用到前面 IE 缓存的问题 在 url 后面加上一个时间戳,会返回 304 错误,原本的内容会被服务器缓存接着用 注意一下
<script>let x = nullconst btns = document.querySelectorAll('button')btns[0].onclick = function () {x = new XMLHttpRequest();x.open('GET', 'http://127.0.0.1:8000/delay?t='+Date.now())x.send()}btns[1].onclick = function () {x.abort()}
</script>
取消请求的结果:
五、AJAX 请求重复发送问题
之前用户连续点击按钮 AJAX 一直向服务器发送请求,但是我们不想这么做,我们想让用户连续点击时 取消前一次发送,进行下一次发送 有点像 js 中的防抖,有利于性能提升
我们就加入一个标识变量 isSending 检测 是否发送请求,如果有请求就把之前的请求取消,然后设置 isSending 为 true 然后检测是否发送结束,如果服务器返回全部内容时 就是
xhr.readyState === 4 时就认定发送结束了,然后设置 isSending 为 false
不要判断响应的状态码 因为有可能这个请求有可能不成功 不是 2 开头 一直在成功里面判断isSending 就不能为 false了 不能继续进行下去了
<script>let x = null// 标识变量 看是否在发送 AJAX 请求let isSending = falseconst btns = document.querySelectorAll('button')btns[0].onclick = function () {// 判断标识符变量if(isSending) x.abort()x = new XMLHttpRequest();// 修改 标识变量的值isSending = truex.open('GET', 'http://127.0.0.1:8000/delay?')x.send()xhr.onreadystatechange = function () {// 在里面处理服务端返回的结果 在 4 时再处理if (xhr.readyState === 4) {// 判断响应的状态码 200 404 403 401 500// 2 开头都表示成功isSending = false}}}
</script>