盘点前端的那些Ajax请求:从ES5到React
说起前端开发,Ajax请求是绕不开的技术点。然而,程序语言更新换代越来越快,Ajax请求的方式也是各有不同。
在使用ES5开发的时候,我们还在使用最原始的XMLHttpRequest对象:
// createXHR函数,返回浏览器支持的异步请求对象
function createXHR() {
if(typeof XMLHttpRequest != "undefined"){
return new XMLHttpRequest(); // IE7+、Firefox、Opera、Chrome、Safari
}
else if(typeof ActiveXObject != "undefined"){
return new ActiveXObject("Microsoft.XMLHTTP"); // IE7及以前版本的浏览器
}
else{
throw new Error("No XHR object available.");
}
}
var xhr = createXHR(); //创建XHR对象
xhr.onreadystatechange = function(){ //readyState状态改变及触发onreadystatechange事件
if(xhr.readyState == 4){ //readyState状态改变可从0到4,4表示所有数据已就绪
if((xhr.status >= 200 && xhr.status <300) || xhr.status == 304){ //status为200,响应成功;status为304,表示请求的资源未被修改
alert(xhr.responseText); //responseText表示响应主体返回的文本
} else {
alert("Request was unsuccessful: " + xhr.status);
}
}
};
xhr.open("get", "test.php?uid=1&name=xiaoming", true); //启动一个请求以备发送
xhr.send(null);
上面是get请求方式。
发送相同量数据时,get比post快得多,所以如无必要,应尽量使用get请求方式。
post可以发送更多的数据,且不限格式。
post请求需要添加额外的请求头,并把发送数据放在send方法中,如:
xhr.open("post", "test.php", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // post请求需要设置Content-Type
var form = document.getElementById("user");
xhr.send(serialize(form)); // 假如form是一个表单节点,serialize()序列化了表单数据
/*
假如需要发送的数据是一个对象,如data,也可以使用JSON.stringify(data)把数据字符串化,在使用send()方法发送
*/
后来出现了JQuery ,极大的简化了Ajax请求的代码编写,几乎只需要一行代码。
$.ajax({
url: "demo_test.php",
type: "POST",
data: {name: 'xiaoming'},
success: function(result, status, xhr){
alert(result);
},
error: function(result, status, xhr){
alert('错误:'+status);
}
});
单独使用post请求,也可以写成:
$.post("test.php", {uid:'001'}, function(data,status,xhr){
alert(data);
});
单独使用get请求,也可以写成:
$.get("test.php",{name: 'xiaom'}, function(data,status,xhr){
alert("数据: " + data + "\n状态: " + status);
});
到ES6出现的时候,有了新的对象 Promise ,它带有的then和catch方法可以获取异步执行代码的数据,我们就可以把ajax请求获取的数据取出,做我们想要的操作。
根据需要,我们可以把ajax请求放在一个Promise对象中:
function ajax(URL) {
return new Promise(function (resolve, reject) {
// createXHR函数,返回浏览器支持的异步请求对象
function createXHR() {
if(typeof XMLHttpRequest != "undefined"){
return new XMLHttpRequest(); // IE7+、Firefox、Opera、Chrome、Safari
}
else if(typeof ActiveXObject != "undefined"){
return new ActiveXObject("Microsoft.XMLHTTP"); // IE7及以前版本的浏览器
}
else{
throw new Error("No XHR object available.");
}
}
var xhr = createXHR(); //创建XHR对象
xhr.onreadystatechange = function(){ //readyState状态改变及触发onreadystatechange事件
if(xhr.readyState == 4){ //readyState状态改变可从0到4,4表示所有数据已就绪
if((xhr.status >= 200 && xhr.status <300) || xhr.status == 304){ //status为200,响应成功;
//status为304,表示请求的资源未被修改
resolve(xhr.responseText); //responseText表示响应主体返回的文本
} else {
reject("Request was unsuccessful: " + xhr.status);
}
}
};
xhr.open("get", "test.php?uid=1&name=xiaoming", true); //启动一个请求以备发送
xhr.send(null);
});
}
获得的数据可以使用then和catch方法处理:
ajax('test.php').then((value) => {
alert(value); // 请求成功
}).catch((error) => {
alert(error); // 请求失败
});
也可以使用async和await获取:
async function getData(){
try {
const responceText = await ajax();
alert(responceText);
} catch (error) {
alert(error); //输出异常错误
}
}
getData();
而对于React来说,它是组件化编程方式,如果你想在组件初次渲染时就展示ajax请求获取的数据,我们一般把ajax请求放在生命周期钩子componentDidMount中:
class User extends React.Component {
// ......
componentDidMount() {
// 以JQuery的ajax请求举例
this.serverRequest = $.get('test.php', {uid: '001'},function (result) {
// 用获取的数据更新组件的state数据
this.setState({
username: result.username,
lastTime: result.lastTime
});
}.bind(this));
}
// 组件卸载,销毁未结束的请求
componentWillUnmount() {
this.serverRequest.abort();
}
// ......
}
如果需要用户的操作(如:点击按钮)以获取数据,请将ajax请求放在onClick事件句柄函数中。
新版的React推荐使用函数式组件,那就没有生命周期函数了,一般把第一次渲染后需要的ajax请求放在React Hook Effect中:
import { useEffect, useState } from 'react';
const [username, setUsername] = useState('');
const [lastTime, setLastTime] = useState('');
// 在开发环境,组件渲染之后,Effect会执行两次,第一次是调试
// 为了不更新两次数据,需要设置清理函数
// 在生产环境,Effect只会执行一次
let ignore = false;
useEffect(() => {
// 以JQuery的ajax请求举例
// 如果是初次请求,ajax请求数据,更新state
if(!ignore){
$.get('test.php', { uid: '001' },function (result) {
setUsername( result.username );
setLastTime( result.lastTime );
});
}
// 清理函数,第一次请求之后,把ignore设为true,第二次请求时不会再获取数据
return () => {
ignore = true;
};
}, []);
盘点前端的那些Ajax请求:从ES5到React的更多相关文章
- phpStudy4——前端页面使用Ajax请求并解析php返回的json数据
项目需求: 在html页面显示所有用户列表信息. 需求分析: 1. html页面使用ajax向后端php请求用户数据 2. php脚本查询数据库,并将查询后的结果以json格式返回前端html页面 3 ...
- 前端javascript发送ajax请求、后台书写function小案例
HTML端页面: <td> <input class="pp_text" type="text" name="" valu ...
- [Web 前端] 如何在React中做Ajax 请求?
cp from : https://segmentfault.com/a/1190000007564792 如何在React中做Ajax 请求? 首先:React本身没有独有的获取数据的方式.实际上, ...
- spring security:ajax请求的session超时处理
当前端在用ajax请求时,如果没有设置session超时时间并且做跳转到登录界面的处理,那么只是靠后台是很难完成超时的一系列动作的:但是如果后台 没有封装一个ajax请求公共类,那么在ajax请求上下 ...
- react中使用Ajax请求(axios,Fetch)
React本身只关注于界面, 并不包含发送ajax请求的代码,前端应用需要通过ajax请求与后台进行交互(json数据),可以使用集成第三方ajax库(或自己封装) 常用的ajax请求库 jQuery ...
- ajax请求下载Execl表
Execl表是经常要用到的存放二位数据的表格,Java也可以直接操作Execl表,经常用到的方式就是jxl和poi. 在这次项目中,我用到的poi往Execl中写数据,刚开始设计的是前端发送一个aja ...
- springmvc 前端 发ajax请求的几种方式
一.传json单值或对象 1.前端 var data = {'id':id,'name':name}; $.ajax({ type:"POST", url:"user/s ...
- BBS(第一天)项目之 注册功能实现通过forms验证与 前端ajax请求触发查询数据库判断用户是否存在的功能实现
1.BBS项目之注册功能通过forms验证 from django import forms from blog.models import User from django.contrib.auth ...
- 前端通信:ajax设计方案(七)--- 增加请求错误监控、前端负载均衡以、请求宕机切换以及迭代问题修复
距离上个迭代过了很长时间,中间经历了很多事情,也在每个空余时间构思了这个迭代的东西以及下个迭代要做的东西.时间周期稍微长了,望见谅. 而且,至今这个开源库的start也已经到了165个了,会支持关注和 ...
- 前端通信:ajax设计方案(六)--- 全局配置、请求格式拓展和优化、请求二进制类型、浏览器错误搜集以及npm打包发布
距离上一次博客大概好多好多时间了,感觉再不搞点东西出来,感觉就废了的感觉.这段时间回老家学习驾照,修养,然后7月底来上海求职(面了4家,拿了3家office),然后入职同程旅游,项目赶进度等等一系列的 ...
随机推荐
- 在 Net7.0环境下测试了 Assembly.Load、Assmebly.LoadFile和Assembly.LoadFrom的区别
一.简介 很长时间没有关注一些C#技术细节了,主要在研究微服务.容器.云原生.编批等高大上的主题了,最近在写一些框架的时候,遇到了一些和在 Net Framework 框架下不一样的情况,当然了,我今 ...
- 使用js开发一个快速打开前端项目的alfred插件
使用js开发一个快速打开前端项目的插件 目录 前言 使用的技术栈 步骤 问题发现 待优化 前言 一直以来开发都是先打开vscode,然后选择项目,在项目多的情况下会觉得挺繁琐:如果同时打开了许多vsc ...
- Linux系列教程——Linux文件查找、Linux压缩打包、Linux软件管理
@ 目录 1 Linux文件查找 1.find查找概述 2.find查找示例 1.find名称查找 2.find大小查找 3.find类型查找 4.find时间查找 5.find用户查找 6.find ...
- Newstar CTF 2023
WEEK1 PWN 1.ezshellcode 直接sendline(shellcode)即可 exp: from pwn import * p = remote("node4.buuoj. ...
- 21.2 Python 使用Scapy实现端口探测
Scapy 是一款使用纯Python编写的跨平台网络数据包操控工具,它能够处理和嗅探各种网络数据包.能够很容易的创建,发送,捕获,分析和操作网络数据包,包括TCP,UDP,ICMP等协议,此外它还提供 ...
- YbtOJ 「图论」第3章 最短路径
例题1.单源最短路径 dij 板子.(w36557658 原版 dij 代码! code #include<cmath> #include<queue> #include< ...
- U盘插入过手机后再拔出来,windows无法识别的解决办法
win键+X,设备管理器. 找到"通用串行总线控制器",大容量USB设备,右键,卸载设备. 拔出U盘,再插入U盘. 就好了. 很明显,U盘插入手机,然后设置里点弹出后再拔,这是很规 ...
- matlab快速入门笔记
命名规则: clc:清除命令行的所有命令 clear all:清除所有工作区的内容 注释:两个% + 空格 %% matlab的数据类型 1.数字 3 3 * 5 3 / 5 3 + 5 3 - 5 ...
- QLabel自己总结(常用接口)
继承关系:QLabel->QFrame->QWidget void setText(const QString &) [slots] 设置标签显示的内容,也可以使用构造函数设置. ...
- Net 高级调试之七:线程操作相关命令介绍
一.简介 今天是<Net 高级调试>的第六篇文章.上一篇文章我们说了值类型,引用类型,数组等的内存表现形式.有了这个基础,我们可以更好的了解我们的程序在运行时的状态,内存里有什么东西,它们 ...