前端后端交互系列之原生Ajax的使用
目录
- 前言
- 一,Ajax概述
- 二,基础知识之Http协议
- 2.1 请求报文
- 2.2 响应报文
- 2.3 如何查看通信报文
- 三,Ajax简单案例
- 3.1 Express框架创建服务端
- 3.2 Ajax案例后台准备
- 3.3 Ajax案例前台准备
- 3.4 发送get请求
- 3.5 发送带有参数的Ajax请求
- 3.6 发送post请求
- 3.7 POST设置请求体
- 四,其他问题
- 4.1 ajax服务端响应json数据
- 4.2 IE浏览器缓存问题
- 4.3 Ajax请求超时与异常处理
- 4.4 ajax取消请求
- 4.5 ajax请求重复发送问题
- 后记
前言
学习前端,我们可以还原最基本的结构和样式。但是离真实的应用还差了很多,打开大公司的网站或软件,用户可以在页面上看到实施的数据,能对一些数据进行简单的操作。而我们之所以要学习前后端交互就是为了从服务器获取相关的数据,并把它们放在自己的页面上。
在Vue中会用到axios,是对Ajax的封装。本片文章其实是在为Axios作铺垫,所以是系列文章之一。适合有基础的读者阅读。最好懂得Ajax的基本原理用法与nodejs的相关知识。
一,Ajax概述
Ajax是前后端交互的一种工具
优点:
可以无需刷新页面与服务器端进行通讯;
允许根据用户事件来跟新部分页面内容。
缺点:
没有浏览历史,不能回退;
存在跨域问题;
SEO不友好。(搜索引擎优化)
二,基础知识之Http协议
Http协议详细规定了浏览器和万维网服务器之间相互通信的规则。
Http协议是一种约定,约束了请求与响应。发送的内容叫做请求报文,响应的结果叫做响应报文。
2.1 请求报文
完整http请求报文:
行:请求类型/url路径/http版本(最多的是1.1);
头:Host,Cookie,Content-type,User-Agent,都是键值对;
空行
请求体:可有可无,get请求体是空的,post可有可无。
2.2 响应报文
行:HTTP/版本 状态码 响应状态字符串
头:Content-Type,Content-length,Content-encoding等,都是键值对;
空行
体:html结构;
2.3 如何查看通信报文
F12,刷新,network(网络)
随机点开一个,都是网络请求,可以随意查看学习。
三,Ajax简单案例
3.1 Express框架创建服务端
Express是基于Node.js平台的一个框架,由于学习过程中我们需要一个服务端,所以可以低成本学习一下。
详学Nodejs的时候,也会接触到。
详细请参考数据。现在我以自己的电脑作为服务器,创建一个服务端,下面是代码部分,复制粘贴后可以使用node运行:
//1.引入express
const express = require('express');
//2.创建应用对象
const app = express()
//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/', (request, response) => {//设置响应response.send('Hello Express');
})app.listen(8000, () => {console.log('服务器已启用,8000端口监听中...')
})
创建完毕后:
可以在127.0.0.1:8080中看到内容及相关网络请求:
3.2 Ajax案例后台准备
首先准备一个后台:
//1.引入express
const express = require('express');
//2.创建应用对象
const app = express()
//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/server', (request, response) => {//设置响应头response.setHeader('Access-Control-Allow-Origin', '*')//设置响应体response.send('Hello Ajax');
})app.listen(8000, () => {console.log('服务器已启用,8000端口监听中...')
})
这里我来解释下:我们在发送请求的时候,通常看接口文档,后面都会告诉你接口地址,我们发送请求的url通常是baseURL+url,而url就是这里的url。
当我们修改后台代码后,需要重启一下后台。
现在访问127.0.0.1:8000/server就可以看到,相关信息。包括响应体与响应头的设置,都是正常显示的:
3.3 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><style>div {width: 200px;height: 200px;border: 1px solid rebeccapurple;}</style>
</head>
<body><button>发送get请求</button><div></div>
</body>
</html>
3.4 发送get请求
本节的目的是,用ajax发送请求。先从get请求开始。
运行刚刚写好的后台,并在前台为按钮绑定点击事件,当点击按钮后,发送get请求。
请认真阅读下面代码及代码中的数据。
<script>const btn = document.querySelector('button')btn.addEventListener('click',function() {//创建对象const xhr = new XMLHttpRequest();//初始化,设置请求方法和urlxhr.open('GET', 'http://127.0.0.1:8000/server'),//发送xhr.send();//吹服务端返回结果//readstate是状态 0:初始,1:open调用完毕,2:send调用完毕,3:服务端返回部分结果,4:服务端返回所有结果//这里的意思是,当readstate发生改变的时候触发xhr.onreadystatechange = function() {//判断状态是否是4,表明服务端返回所有结果if(xhr.readyState === 4) {//状态2开头都是成功if(xhr.status >= 200 && xhr.status < 300) {//处理结果 行,头,空行,体//1.响应行console.log(xhr.status)console.log(xhr.statusText)//响应状态码console.log(xhr.getAllResponseHeaders());//所在响应头console.log(xhr.response)//响应体}}}} )
</script>
</html>
运行后即可获得结果:
能打印出来则代表运行成功,成功后我们可以把返回的响应体放到div中,注意在做这件事情之前需要把div给绑定了,这里我给div取名为box。
最后即可在框中看到响应体:
3.5 发送带有参数的Ajax请求
平时我们在使用过程中都是在地址栏中传参,在ajax中该如何传参?
在url中,用问号衔接,用&符号分割
我们可以直观的看到请求:
3.6 发送post请求
发送post请求的步骤和发送get请求的步骤十分类似。
但是后台代码需要加上跟post相关的接口,如下:
//post请求的响应接口
app.post('/server', (request, response) => {//设置响应头response.setHeader('Access-Control-Allow-Origin', '*')//设置响应体response.send('Hello Ajax');
})
前台的需求是,有一个盒子,鼠标碰到之后,盒子上显示出post请求后的响应。post请求的发送方式与get非常类似,唯一不同的地方就是get需要换成post,代码如下:
<body><div class="box">当鼠标放到div盒子上的时候发送post请求,最后出来的结果是:</div><script>//获取元素对象const box = document.querySelector('.box')box.addEventListener('mousemove', () => {//第一步创建对象const xhr = new XMLHttpRequest();//初始化,设置请求类型与urlxhr.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) {//处理服务端返回结果box.innerHTML = xhr.response;}}}})</script>
效果如下:
3.7 POST设置请求体
什么是请求体?也就是post请求需要传递的参数。
post一般代表提交。一般在表单中,post可以把表单的内容发送给服务器,并且服务器会做出响应。
post请求一般在send中发送:
格式如上即可。
四,其他问题
4.1 ajax服务端响应json数据
在实际应用中,我们向服务端发起请求,服务端响应结果,绝大多数都返回一个json格式的数据。我们应当如何处理?
刚刚我们已经学习了get和post,并且会通过response.send方法返回信息。刚刚返回的都是一句话:
现在我想返回一个对象:
返回对象不能直接放到send中,因为send只能接收字符串类型,所以要对data进行一个数据转化,使用JSON.stringify(data),这样的话data中的数据就会转化成字符串形式,就可以正常使用send了。操作如下:
//给json-server发送请求
app.get('/json-server', (request, response) => {response.setHeader('Access-Control-Allow-Origin', '*')//响应一个数据const data = {name: 'qklxmy'}response.send(JSON.stringify(data))})
结果同样也是一段json格式的字符串:
我们该如何从中提取到想要的数据?
我们接收到的数据是xhr.response:
我们可以使用parse方法,将json格式的数据解析成字符串:
xhr.onreadystatechange = function () {if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300) {//解析json信息const data = JSON.parse(xhr.response);//直接取用data中的值box.innerHTML = data.name}}}
解析后直接取用即可,最后效果:
4.2 IE浏览器缓存问题
IE浏览器会对Ajax请求结果进行缓存,导致下次发起请求走的是本地的缓存而不是服务器的最新数据。
解决方法,在url中加一个时间戳就可以解决问题了。
4.3 Ajax请求超时与异常处理
Ajax网络异常时,可以给用户来一个提醒,加强产品体验。
首先,我们需要处理一下,让ajax请求超时,可以用到定时器:
//延时响应
app.get('/longtime', (request, response) => {response.setHeader('Access-Control-Allow-Origin', '*')//定时器setTimeout(() => {response.send('helloabaaba');}, 2000)
})
前台还是一个按钮,点击按钮后发出请求。
接着我们对前台代码进行一个延时两秒的处理,两秒钟之内如果没有结果请求就取消
这样的话,最后的效果就是没有效果。
我们还可以加一个超时的回调:
最后效果:
前台代码部分:
<body><div class="box"></div><button class="btn">点击发送请求</button><script>var box = document.querySelector('.box')var btn = document.querySelector('.btn')btn.addEventListener('click', () => {const xhr = new XMLHttpRequest();//2s内如果没有结果这个请求就取消xhr.timeout = 2000;//超时的一个回调函数xhr.ontimeout = () => {alert('网络异常,请稍后重试!')}xhr.open('GET', 'http://127.0.0.1:8000/longtime');xhr.send();xhr.onreadystatechange = function() {if(xhr.readyState === 4) {if(xhr.status >= 200 && xhr.status < 300) {box.innerHTML = xhr.response;}}}})</script>
</body>
4.4 ajax取消请求
使用abort函数即可:
//取消请求btn2.addEventListener('click', () => {xhr.abort();})
4.5 ajax请求重复发送问题
什么是ajax请求重复的问题呢,比如我们的前端页面有一个发送按钮:
每点击一下就会发送个请求:
但是如果我们的服务端响应比较慢,用户疯狂点击,服务器就会接收到非常多的一样的请求。
这个问题的解决方法:让服务器判断之前是不是有一样的请求。如果有就不执行,执行最新的这个请求。这样可以减缓服务器的压力,提高效率和性能。
以上是方向,现在说原理。设置一个标识符,用来标识是否在发ajax请求。如果正在发送,则取消该请求,创建一个新的请求
代码如下:
<body><button class="btn">点击发送</button><script>let x = null;//设置一个标识符,是否在发送ajax请求let isSending = false;var btn = document.querySelector('.btn')btn.addEventListener('click', () => {if(isSending) x.abort();x = new XMLHttpRequest();isSending = true;x.open('GET', 'http://127.0.0.1:8000/server');x.send();x.onreadystatechange = function() {if(x.readyState === 4) {isSending = false;}}})</script>
</body>
后记
以上就是原生Ajax的基本使用。
后面会连载这个系列的文章,包括jq下的Ajax,Axios,Promise,Nodejs,甚至一些项目中遇到的实例。欢迎关注。
相关文章:

前端后端交互系列之原生Ajax的使用
目录前言一,Ajax概述二,基础知识之Http协议2.1 请求报文2.2 响应报文2.3 如何查看通信报文三,Ajax简单案例3.1 Express框架创建服务端3.2 Ajax案例后台准备3.3 Ajax案例前台准备3.4 发送get请求3.5 发送带有参数的Ajax请求3.6 发送post请求3.…...

openGauss 5.0企业版主从部署,实战狂飙
📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…...
Vue中props组件和slot标签的区别
在 Vue 中,props 和 slot 都是组件之间进行通信的机制,它们的作用和应用场景有一些区别: props 是一种组件的数据传递机制,通过在父组件中以属性的形式向子组件传递数据。子组件接收这些数据,并可以进行相应的处理和渲…...

基于Windows下VSCode搭建Vue开发环境
一、准备工作 VSCode编辑器安装:https://code.visualstudio.com/Node.js安装:https://blog.csdn.net/qq_40197828/article/details/78302124VSCode插件安装:Vetur和ESlint 二、更换淘宝镜像源 更换镜像源命令:npm install -g c…...

Android开发 Dialog对话框 DatePickerDialog
1. AlertDialog AlertDialog是弹出的提醒对话框,有提示,确认,选择等功能。 没有公开的构造方法,一般用AlertDialog.Builder来完成参数设置,最后调用create方法创建。 参数设置常用的方法: 代码ÿ…...
开心档开发入门网之C++ Web 编程
C Web 编程什么是 CGI?公共网关接口(CGI),是一套标准,定义了信息是如何在 Web 服务器和客户端脚本之间进行交换的。CGI 规范目前是由 NCSA 维护的,NCSA 定义 CGI 如下:公共网关接口(…...

C# 和 VB .NET 的纯 FFmpeg 包装器:CSFFmpeg Crack
用于 C# 和 VB .NET 的纯 FFmpeg 包装器buildbuildpassingpassing releasereleasev1.0.3.0v1.0.3.0用于 C# 和 VB .NET Framework(WinForm 和 WPF)和 .NET Core 的纯 FFmpeg 包装器。 截图 主要 Winform 示例有据可查的例子目录: 关于截图好处…...
python外篇(序列化和非序列化)
目录 概念阐述 pickle json msgpack 概念阐述 序列化是指将对象转化为可存储或可传输的数据格式,例如将 Python 对象转化为二进制、JSON 或 XML 等格式,以便于将其存储到文件中或在网络上传输。在Python中,可以使用pickle、json、msgpac…...

Linux总结(二)
基础IO 1.什么叫文件? 我们需要在操作系统的角度理解文件。 文件 = 文件内容 + 属性(所以即使是空文件,也会占空间,因为我们是需要保存文件属性的,属性也是数据,所以占空间) C/C++程序默认会打开三个文件流,叫做标准输入(stdin),标准输出(stdout),标准错误(std…...

【4.1】Socket编程、TCP挥手
TCP连接断开 四次挥手 四次挥手过程 客户端发送FIN报文,客户端进入FIN_WAIT_1状态。 服务端接收报文,发送ACK报文,服务端进入CLOSE_WAIT状态。 客户端收到ACK报文,进入FIN_WAIT_2状态。 服务端处理完数据后,也发送…...

【竞赛经历】CSDN第41期竞赛题解
1 前言 本次的竞赛主要是最后一题,对于完全不懂珠算的人来说还是有点困难的,仅理解题目的意思就花了很多时间,最后侥幸拿了第一个前三。。。 2 题解 本次竞赛分为编程题部分和非编程题部分,其中非编程题部分比较简单。 2.1 非编…...

【Linux学习】信号——预备知识 | 信号产生 | 核心转储
🐱作者:一只大喵咪1201 🐱专栏:《Linux学习》 🔥格言:你只管努力,剩下的交给时间! 信号🔔信号🎵预备知识🎵信号处理方法的注册🔔信号…...

2023中国程序员薪酬报告出炉,你拖后腿了吗?
程序员薪资高已是公认的事实,但是具体高到什么程度呢?近期,全球人力服务公司 Michael Page Internatioal 就发布了《2023 中国大陆薪酬报告》,揭示了中国程序员的薪酬情况。 该报告中一共调研了国内 7 个行业以及 6 大城市不同职…...

Mac下Python3安装及基于Idea开发
本篇文章带大家基于Mac OS操作系统,下载、安装Python环境,并基于Idea编写第一个Demo。 Python3安装 访问Python官网:https://www.python.org/。找到“Download”菜单,点击下载: 此处下载的为Mac的安装包,…...

2017年 团体程序设计天梯赛——题解集
前言: Hello各位童学大家好!😊😊,茫茫题海你我相遇即是缘分呐,或许日复一日的刷题已经让你感到疲惫甚至厌倦了,但是我们真的真的已经达到了我们自身极限了吗?少一点自我感动…...

“唯一靶点”的华堂宁会成控糖爆品吗?
一上市,两次“断货”的货华堂宁有爆品那味儿了。 2022年10月28日华领医药-B(02552.HK)公告华堂宁(多格列艾汀)正式进入商业化,一周后各个渠道便进入到了断货和限售的状态。 对于一个不在传统九大降糖药品…...

Spring《三》DI依赖注入
🍎道阻且长,行则将至。🍓 上一篇:Spring《二》bean的实例化与生命周期 下一篇:敬请期待 目录一、setter注入🍉1.注入引用数据类型2.注入简单数据类型二、构造器注入🍊1.注入引用数据类型2.简单数…...

leetcode 面试题 17.06. 2出现的次数
编写一个方法,计算从 0 到 n (含 n) 中数字 2 出现的次数。 示例: 输入: 25 输出: 9 解释: (2, 12, 20, 21, 22, 23, 24, 25)(注意 22 应该算作两次) 该问题用的方法数数组dp,首先我通过总结规律写出了相关的code。使用一个dp数组记录10i10^i10i以内会出…...
CMake入门教程【基础篇】5.configure_file构建配置
configure_file配置文件 文章目录 知识点实例代码目录代码实现知识点 configure_fileconfigure_file 源文件转换为目标文件 实例 代码目录 |-📁prj4 |-- 🎴CMakeLists.txt |-- 🎴TutorialConfig.h.in |-- 🎴tutorial.cxx 代码实现 /prj4/CMakeLists.…...

软件开发可行性分析——健康食谱小程序
关于软件开发可行性分析先给大家介绍下面几个关键点: 什么是可行性分析? 检查并确定是否值得为项目或产品投入时间、金钱和资源。这样的评估活动称为“可行性分析”。 为什么要进行可行性分析? 在软件项目开发过程中,只要资源…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...