前言
我们访问百度网站,数据都是来自百度服务器,百度服务器有个网线连接着万维网,我们电脑也连接着万维网,以前靠的是电磁波,现在靠的是光纤,前端网络请求发给百度服务器,前端代码生效在用户上,前端发送请求,百度服务器有段后端代码就会响应请求,从数据库上把数据发过来,读到数据,通过一个网络请求发到前端,这就是前后端宏观交互过程
所谓服务器就是一台没有屏幕的电脑,既然没有屏幕用windows也是浪费,一般都是用linux系统,里面会装一个软件叫做数据库,它可以帮服务器打理数据,数据一般就是字符,数字,图片,图片地址等
今天我们要带大家认识下前端如何向后端发送请求的,认识下这些方法的更新迭代
ajax
在JavaScript中发送请求就是ajax,ajax全称为:Asynchronous JavaScript and XML
async是异步的意思,XML你可以立即为html中拓展出的一部分功能。
这里是我们向网易云的服务器发送http请求,服务器会有一个安全策略,不可能谁都可以请求,比如国内的墙,国内的地址我们都可以访问,能访问的地址都放在白名单中。
国内有个大佬做了个开源项目,做了个Node版本的网易云API,里面有很多网易云接口,人家把网易云的数据爬了出来,一般爬数据有两种方式,一种是直接去页面官网爬,另一种是爬人家服务器,这种不过是违法的。这个大佬的方法然而是爬网易云服务器的数据,不过网易云也没说什么,可能那些信息都是非vip都可以看的:laughing:
大佬项目网址:neteasecloudmusicapi.js.org/#/?id=netea…
你可以将项目下载下来,然后在项目路径下打开终端node app.js
可以看到后台被访问的数据
我们这里简单做一个demo,新歌速递:新歌速递
先将localhost改为当前设备的ip地址,然后看文档,后面接参数就可以访问到数据,比如我这里:http://172.22.22.71:3000/top/song?type=8
这里安利一个浏览器插件👍,JSONVue
,看网页JSON数据就有格式了,要不然就是密密麻麻的数据
这里有三种方法处理请求,这个demo就是我点击一个按钮,然后帮我把这些歌曲数据全部列出来
第一种:XMLHttpRequest
这是最原始发接口请求的写法。
<body>
<button id="btn">新歌速递</button>
<ul id='ul'>
</ul>
<script>
const btn = document.getElementById('btn')
btn.addEventListener("click", () => {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'http://172.22.22.71:3000/top/song?type=7', true)
xhr.onreadystatechange = () => {
if(xhr.readyState === 4 && xhr.status === 200){
let result = JSON.parse(xhr.responseText);
result.data.forEach( (song) => {
console.log(song.name);
let li = document.createElement('li')
li.innerHTML = song.name
document.getElementById('ul').appendChild(li)
})
}
}
xhr.send()
})
</script>
</body>
-
let xhr = new XMLHttpRequest()
:这个构造函数用于网络请求,里面有个方法可以直接促使浏览器发送一个http请求 -
xhr.open('GET', 'url', true)
:请求前的准备工作。get是一种请求类型,常见的请求类型有两种,一种就是这里的get,还有一种是post,get是要东西,post是送东西,其实还有很多种,比如put,delete,patch,options等,这些90%都用不上;第二个参数是朝哪里要;第三个参数是控制请求是同步还是异步,这里true(异步)和false(同步)都可以,网络请求耗时一定是异步,你可以用false强行改成同步。绝大多数都是用true,改成同步会阻塞后面代码。还有第四第五个参数,不过一般都用不上。 -
xhr.send()
:发送请求,当然http请求发送后我们需要等它返回的结果,也就是接收响应,一般接收响应的代码会写在发送的前面 -
xhr.onreadystatechange
:接收后端响应 -
xhr.responseText
:实例对象身上的这个属性就是后端的响应。到这里,这些代码就已经构成了JavaScript网络请求的发送以及监听。 -
let result = JSON.parse(xhr.responseText)
:responseText
是JSON字符串,JSON.parse()
将它转成JavaScript对象,有时候后端老哥可能比较贴心,已经给你转成对象了,没有得话就我们自己转 -
result.data.forEach()
:forEach
接收三个参数,item,index,arr,这里只需要每一项,我们可以自行打印result,在控制台中看返回的对象的key,然后找到歌名 -
let li = document.createElement('li')
:创建dom
结构li
-
li.innerHTML = song.name
:往li
中添加值,这里写li.innerText
也可以 -
appendChild(li)
:添加子元素
因此每一次循环都会创建一个li
,并且会塞值进去
效果如下:
if(xhr.readyState === 4 && xhr.status === 200)
:为何还需要额外的if判断?
看完下面的数字的含义你就懂了
readyState
readyState
有5个值,0到4。代码从上往下执行的时候,执行到onreadystatechange
还在等send执行完后端发送过来数据。
-
readyState === 0
代表刚刚创建xhr
对象。 -
readyState === 1
代表已经准备好了请求体。 -
readyState === 2
代表已经开始调用send了,客户端接收到了响应头(含配置信息)。 -
readyState === 3
代表正在接收响应体,正在解析。是这样的,后端返回的数据是数据包,浏览器需要对他进行解析。 -
readyState === 4
数据解析完成,解析是为了对人看的
status
status就是http的状态码,面试常考这个,务必背下来
面试官:请你把http的状态码从2开头的开始聊下
所有的程序员都需要懂这个,无论前后端,一个情景你就懂了:假设你现在是个前端初级小白,工作时向后端请求数据,结果报了个5开头的错误,然后你以为是自己的错误,在位置上吭哧吭哧地找了两个小时的错误,2个小时后实在是忍不了去问后端老哥,自己代码报错了找不出问题,然后后端老哥就问你,为什么不早点来找我,5开头肯定是我的错误啊。这个时候你就想扇自己耳光了。如果是4开头的错误,你去找后端,后端老哥可能要扇你耳光了。懂http状态码可以有效地提高前后端工作的效率
200:请求被正确处理并返回了结果
201:新增或修改数据成功
202:请求以进入任务队列,被异步处理
203:令牌或登录状态失效
204:删除数据成功
301:请求的资源被永久重定向到新的位置,将从新的地址重新请求
302:请求的资源被临时重定向到新的位置
400:请求参数错误,服务器没有对数据做新建或修改
401:无访问权限,用户名、密码、令牌错误
403:得到访问授权,但访问被进制
404:访问的是不存在的资源
405:请求的方式不正确
406:请求的数据格式不是服务接收的类型
410:请求的资源被永久删除
422:服务器创建对象时发生错误
500:服务器不可用,未返回正确的数据
502:服务器网关错误
503:服务器过载或维护中
504:服务器响应超时
第二种:Jquery-ajax
往往我们会有很多接口请求,用第一种方法每次发接口请求就需要那几行代码,Jquery封装了一个响当当的方法ajax
,和js的ajax重名了。它只需要传入请求的地址和请求类型就可以。手写ajax也是个考点,以后有空再聊
面试官:Jquery中ajax是如何封装的
Jquery现在很多人不用了,不是因为不好用了,只是时代变了。Jquery问世的时候不仅仅是ajax好用,还有很多封装的数组对象方法都很牛,统治全球的js程序员,现在不怎么用仅仅是因为现在的开发模式变了,Jquery只封装了js,没有html,现在的框架全给你封装好了
这有个网站收纳了全世界所有的框架的源码,做成了在线地址:BootCDN - Bootstrap 中文网开源项目免费 CDN 加速服务,可以在里面找到jquery
复制它的script标签,必须放在你写的script之前,地址里面全是源码
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script>
const btn = document.getElementById('btn');
btn.addEventListener('click',() => {
$.ajax({
url: 'http://172.22.22.71:3000/top/song?type=8',
method: 'GET',
dataType: 'json',
success: function(res){
console.log(res);
res.data.forEach( (song) => {
console.log(song.name);
let li = document.createElement('li')
li.innerHTML = song.name
document.getElementById('ul').appendChild(li)
})
}
})
})
</script>
dataType: 'json'
:告诉后端需要返回json对象格式,人家硬不给也没办法,这里仅仅是为了少点和后端的口头沟通,这是代码沟通
success: function(res){}
:success是当你成功朝着接口地址请求完后的一个响应,其实就是方法一的onreadystatechange
这个success其实就是个回调,成功请求之后拿到数据,success不能拿到外面去,请求是异步的,一定不能拿到外面写
看下控制台是否打印数据
第三种:fetch
es6,promise问世后,官方打造了fetch这个方法专门发接口请求,让原生js自带这个方法
字典mdn中看介绍:Fetch API - Web API 接口参考 | MDN (mozilla.org)
<script>
const btn = document.getElementById('btn');
btn.addEventListener('click',() => {
fetch('http://172.22.22.71:3000/top/song?type=7')
.then(data => data.json())
.then(res => {
console.log(res);
res.data.forEach( (song) => {
console.log(song.name);
let li = document.createElement('li')
li.innerHTML = song.name
document.getElementById('ul').appendChild(li)
})
})
})
</script>
.then
:说明fetch中一定return了一个new Promise
,fetch里面return了从后端拿到的数据
data.json()
:json方法只有data有,把数据格式化
最后
前端向后端发请求,最初是原生js,面对多个请求就很繁琐,然后Jquery横空问世后大家都用Jquery的ajax方法,然后js官方坐不住了,es6推出fetch方法,这个方法用得还是比较多的,但是更多时候我们用得是vue中axios方法。最近一直在写vue的文章,大家感兴趣可以多关注一手。
另外有不懂之处欢迎在评论区留言,如果觉得文章对你学习有所帮助,还请”点赞+评论+收藏“一键三连,感谢支持!
本人GitHub学习仓库:github.com/DolphinFeng…