详谈ajax发展历程

692 阅读9分钟

前言

我们访问百度网站,数据都是来自百度服务器,百度服务器有个网线连接着万维网,我们电脑也连接着万维网,以前靠的是电磁波,现在靠的是光纤,前端网络请求发给百度服务器,前端代码生效在用户上,前端发送请求,百度服务器有段后端代码就会响应请求,从数据库上把数据发过来,读到数据,通过一个网络请求发到前端,这就是前后端宏观交互过程

所谓服务器就是一台没有屏幕的电脑,既然没有屏幕用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可以看到后台被访问的数据

4.png

我们这里简单做一个demo,新歌速递:新歌速递

1.png

先将localhost改为当前设备的ip地址,然后看文档,后面接参数就可以访问到数据,比如我这里:http://172.22.22.71:3000/top/song?type=8

这里安利一个浏览器插件👍,JSONVue,看网页JSON数据就有格式了,要不然就是密密麻麻的数据

2.png

这里有三种方法处理请求,这个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,并且会塞值进去

效果如下:

3.png

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

5.png

复制它的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不能拿到外面去,请求是异步的,一定不能拿到外面写

看下控制台是否打印数据

6.png

第三种: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…

求赞.jpg