前端后端交互系列之原生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();
        //初始化,设置请求方法和url
        xhr.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();
            //初始化,设置请求类型与url
            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) {
                        //处理服务端返回结果
                        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,甚至一些项目中遇到的实例。欢迎关注。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.kler.cn/a/7399.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C的实用笔记39——结构体占用内存大小(了解)

1.结构体成员列表的存储现象 1、知识点&#xff1a; 我们在结构体这个整体中定义的成员变量是挨着的&#xff0c;这让我们容易误以为它们的存储方式也是挨着的&#xff0c;但其实并不是。我们之前用sizeof测过&#xff0c;在gcc编译器下&#xff0c;不论什么类型指针&#xf…

Vue+H5如何适配各个移动端?

前言 我们都知道&#xff0c;在做移动端的项目的时候&#xff0c;我们最首先的是要指定适配各种机型的方案&#xff0c;让一套代码能够在不同分辨率的机型下顺应自如。想知道移动端适配原理的小伙伴可以先移步看看这篇文章&#xff1a;解决移动端适配方法总结&#xff0c;相信…

netty 实现websocket 携带参数建立连接

Netty提供了很好的WebSocket支持&#xff0c;可以通过添加WebSocketServerProtocolHandler实现暴露一个WebSocket接口。但是&#xff0c;如果需要在WebSocket的URI中添加参数queryString&#xff0c;例如/im/ws?w221100234&t99&#xff0c;则连接可能无法建立&#xff0c;…

VSCode卸载、重装配置、常用快捷键

VSCode彻底卸载 彻底卸载VSCode 控制面板卸载VSCode.删除安装插件 winR输入%userprofile%&#xff0c;删除当前路径下的.vscode文件夹。删除用户信息和缓存信息 winR输入%appdata%&#xff0c;删除当前路径下的Code和Visual Studio Code文件夹。 VSCode重装插件配置 Chinese&…

【ChatGPT 】国内无需注册 openai 即可访问 ChatGPT:ChatGPT Sidebar 浏览器扩展程序的安装与使用

一、前言 问题&#xff1a;国内注册 openai 账号麻烦&#xff0c;新必应有部分人也无法登录成功&#xff0c;存在域名单点登录失败等问题&#xff0c;所以无法真正使用 ChatGPT 解决&#xff1a;大部分人仅需使用 ChatGPT 的搜索功能&#xff0c;无需真正对话&#xff0c;需要…

【软件设计师10】软件工程

软件工程 1. 瀑布模型SDLC - 结构化 优点&#xff1a;结构化方法模型&#xff0c;每个阶段分工明确&#xff1b;出现问题可以向上层回溯 缺点&#xff1a;需求阶段难以把控&#xff0c;在项目初期&#xff0c;软件的需求几乎是不明确的&#xff0c;等开发完用户往往再提出问…

SpringSecurity实战解析

文章目录一、Security认证和原理1、认证基本流程1.1 表单认证概述1.2 基本流程分析1.3 权限访问流程2、请求间共享认证信息2.1 概述2.2 获取认证用户信息3、认证的几种方式4、注解权限4.1 概述4.2 Secured注解使用方式4.3 jsr250Enabled4.4 prePostEnabled 规范(重要)5、自定义…

为什么系统的Swap变高了?

我们知道当发生了内存泄漏时&#xff0c;或者运行了大内存的应用程序&#xff0c;导致系统的内存资源紧张时&#xff0c;系统又会如何应对呢&#xff1f;我们知道&#xff0c;这其实会导致两种可能结果&#xff0c;内存回收和 OOM 杀死进程。 我们先来看后一个可能结果&#x…

吴恩达机器学习--逻辑回归

文章目录前言一、普通二分类逻辑回归需求分析程序设计1. 导入数据2. 可视化数据3. 划分数据4. sigmoid函数5. 假设函数6. 损失函数7. 梯度下降算法8. 可视化模型9. 模型准确率10. 试试sklearn库11. sklearn的准确率12. 完整程序二、 复杂二分类逻辑回归需求分析程序设计1. 逻辑…

面向对象编程(基础)5:类的成员之二:方法(method)

目录 5.1 方法的引入 5.2 方法(method、函数)的理解 举例1&#xff1a; 举例2&#xff1a; 5.3 如何声明方法 1、声明方法的语法格式 &#xff08;1&#xff09;一个完整的方法 方法头 方法体。 &#xff08;2&#xff09;方法头可能包含5个部分 &#xff08;3&…

前后端交互系列之跨域问题

目录前言1. 同源策略及跨域2. 跨域解决方案之JSONP3. 设置CORS响应头实现跨域后记前言 我们在做前后端交互的时候&#xff0c;会遇到跨域问题。本节内容将带领读者了解什么是跨域问题&#xff0c;以及跨域问题的解决方法。 1. 同源策略及跨域 我们所了解的Ajax默认是基于同源…

centos7离线安装docker

前言 在没有互联网的情况下想要安装某些软件用docker是十分方便的一种方式&#xff0c;例如oracle。原生的oracle安装是非常麻烦的&#xff0c;本人亲眼目睹一个专门搞oracle的公司的人安装oracle三天没有成功&#xff01;因此不得不学习在没有互联网的情况下使用docker来安装…

vue3之shallowRef以及使用对element-plus table的优化尝试

首先&#xff0c;先大概回顾一下相关概念吧 ref、shallowRef ref 接受一个内部值&#xff0c;返回一个响应式的、可更改的 ref 对象&#xff0c;此对象只有一个指向其内部值的属性 .value。 如果将一个对象赋值给 ref&#xff0c;那么这个对象将通过 reactive 转为具有深层次…

【vscode】检查到已经改正的错误,没有错误却检查到有错误

一、问题背景 下面这个名为test1.c的C代码&#xff0c;在vscode中用扩展code runner工具通过【run code】方式执行时&#xff0c; 出现了诸如’xxx’ does not name a type、‘xxx’ expected unqualified-id before ‘for’、i’does not name a type等错误。 于是本人把所…

[GXYCTF2019]BabyUpload

思路&#xff1a;先测试是否对文件名后缀检测 1,上传一个php文件 上传内容&#xff1a; GIF89a <?php eval($_POST["cmd"]);?>失败&#xff1a; 2&#xff0c;尝试上传其它类型的文件 构造%00截断的.jpg结尾尝试上传&#xff1a; 再次被拦截&#xff1a; …

摸鱼也可以效率翻倍:Python 统计 gitlab 代码量,定量统计发给领导

嗨害大家好鸭&#xff01;我是爱摸鱼的芝士❤ 一、确定需求 需求是公司大领导想要了解每周研发提交的代码量。 因为研发人员比较多&#xff0c; 想着用 python 做个自动化&#xff0c; 定时统计代码量并发送邮件给领导。 二、统计gitlab代码 首先安装第三方库python-gitlab&…

Hadoop基础介绍

Hadoop基础介绍一、总体介绍二、HDFS架构三、MapReduce结构四、YARN架构一、总体介绍 1、定义&#xff1a; 是一个开源的、可靠的、可扩展的分布式计算框架。 2、用途&#xff1a; &#xff08;1&#xff09;数据仓库 &#xff08;2&#xff09;PB级别数据的存储与处理。 3…

JetpackCompose从入门到实战学习笔记13——Compose中实现简单瀑布流

JetpackCompose从入门到实战学习笔记13——Compose中实现简单瀑布流 文章目录JetpackCompose从入门到实战学习笔记13——Compose中实现简单瀑布流1.简介&#xff1a;2.竖向的StaggeredGrid参数&#xff1a;3.简单使用如下&#xff1a;4.竖向瀑布流效果如下&#xff1a;5.横向的…

基于html+css的内容旋转

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

Solon v2.2.7 发布,支持 Java 20

Solon 是一个高效的 Java 应用开发框架&#xff1a;更快、更小、更简单。也是一个有自己接口标准规范的开放生态。 150来个生态插件&#xff0c;覆盖各种不同的应用开发场景&#xff1a; 相对于 Spring Boot 和 Spring Cloud 的项目&#xff1a; 启动快 5 &#xff5e; 10 倍…
最新文章