我正在参加「掘金·启航计划」
前言
在我们手撸ajax之前,我们先来Ajax吧!
Ajax是什么
在我们写前端代码时,我们是不是都苦恼着如何做前后端互通呢?
而今天的主角就是帮我们完成这件事的。所以Ajax的作用就是用于浏览器与服务器之间使用异步数据传输(HTTP 请求),做到局部请求以实现局部刷新。让我们可以请求到服务端的数据用于渲染浏览器端。
Ajax的作用
- 不刷新页面而更新网页(
局部刷新
) - 在页面加载后从服务器
请求
数据 - 在页面加载后从服务器
接受
数据 - 在后端向服务器发送数据
原生JS向后端请求方式
//原生js提供的接口请求方法
let xhr = new XMLHttpRequest()
xhr.open(method, url, async, [user-name], [user-pass])
xhr.onreadystatechange = function() { //监听
if(xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
}
xhr.send([请求主题])
原生JS提供了一个 XMLHttpRequest 方法。我们直接new 一个xhr实例对象。然后我们直接调用XMLHttpRequest上的open方法。同时在open
方法中携带method、url、async(async=false为同步执行)、[user-name]、[user-pass](可选、url的认证资格)。
http 请求方式(method)
- GET: 从服务器获取数据(向服务器推送数据)
- POST: 向服务器推送数据(从服务器获取数据)
- DELETE:删除服务器的某些内容
- PUT: 向服务器存放一些内容
- HEAD: 只想获取服务器返回的响应头信息,不要响应体
- OPTIONS: 一般使用它向服务器发送一个探测请求,如果返回的信息,说明客户端和服务器建立了连接,可以继续请求
- TRACE: 基于cross - domain 进行跨域请求的时候
之后我们继续可以调用XMLHttpRequest 的onreadystatechange
方法用来监听的状态。根据状态码来判断请求是否成功和返回数据。
readyState的状态
- 0: 刚刚创建xhr
- 1:执行了open这个操作
- 2:请求已经发送,响应头已经被客户端接受
- 3: 响应主题正在返回 // 还没被接收
- 4:响应主体已经被客户端接收
http状态码
- 1xx: 请求已经接受,正在处理
- 2xx:成功。请求被成功接受
- 3xx:成功,资源已经重定向了 // 换了个url
- 4xx:客户端错误
- 5xx: 服务端错误
最后我们调用XMLHttpRequest 的send
方法根据情况向后端传递参数。这样我们既完成了原生的JS请求方式。
我们来一个实例
<!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>
</head>
<body>
<!-- 原生的请求方式 -->
<script>
let xhr = new XMLHttpRequest()
xhr.open('GET', 'https://www.fastmock.site/mock/39ac87de3060aa2bb2ba20a0ff375c81/cat-movie/mostLike')
xhr.onreadystatechange = function () { //监听
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(JSON.parse(xhr.responseText));
}
}
xhr.send()
</script>
</body>
</html>
直接使用封装好的Ajax方法
我们先来看一看封装好的Ajax方法的使用方式,我们同样是可以向后端请求到数据,而且会你原生JS的请求方式更加的便捷。
<!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">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<<script>
$.ajax({
url:'https://www.fastmock.site/mock/39ac87de3060aa2bb2ba20a0ff375c81/cat-movie/mostLike',
method: 'GET',
dataType:'json',
data:null,
async: true,
cache: true,
success: res => {
console.log(res);
}
})
</script>
</body>
</html>
手撸一个简化版Ajax
在看完直接封装的Ajax方法,那我们是否好奇它是怎么实现的呢?那接下来我们就来自己封装一个简化版的Ajax来看看他的实现原理吧。
HTML代码:
<!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">
<script src="ajax.js"></script>
<title>Document</title>
</head>
<body>
<script>
ajax({
url: 'https://www.fastmock.site/mock/39ac87de3060aa2bb2ba20a0ff375c81/cat-movie/mostLike',
method: 'GET',
dataType: 'json',
data: {
name: 'abc',
age: 10
},
async: true,
cache: true,
success: res => {
console.log(res);
}
})
</script>
</body>
</html>
JS代码部分:
function ajax(options) {
let { // 结构前端参数
url,
method= 'GET',
data= null,
dataType= 'JSON',
async = true,
cache = true,
success,
error
} = options
let xhr = new XMLHttpRequest()
// 处理参数
if(method.toUpperCase() === 'GET') { // 处理不同的请求方式
if(data) {
url += '?'
for(let key in data) {
url += `${key}=${data[key]}&`
}
xhr.open(method, url, async)
xhr.send()
}
}else { //post
xhr.open(method, url, async)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') // 请求头
xhr.send(data)
}
xhr.onreadystatechange = () =>{ // 监听请求是否成功,并返回数据
if(xhr.readyState === 4){
if( !/^(2|3)\d{2}$/.test(xhr.status)) {
error && error(xhr.statusText, xhr)
}
let result = handleDataType(xhr) //格式化处理
success && success(result, xhr)
}
}
function handleDataType(xhr) { //拿到前端需要的数据格式,进行格式化处理
dataType = dataType.toUpperCase()
let result = xhr.responseText
switch(dataType) {
case 'TEXT':
break;
case 'JSON':
result = JSON.parse(result)
break;
case 'XML':
result = xhr.responseXML
break;
default:
}
return result
}
}
在通过简单的封装,我们自己的封装的Ajax也能实现JQ里封装好的ajax的部分功能。
总结
话已至此,便落下帷幕。学习阶段,欢迎各位大神补充观点。