在网络应用中,前后端的数据交互是必不可少的一部分。本文将带你从最基本的 XMLHttpRequest 开始,逐步了解并掌握 jQuery、fetch 和 Axios 这几种常用的前端网络请求方式。每种方式都有其特点和适用场景,希望通过本文的介绍,你能找到最适合项目的解决方案。
浏览器对XMLHttpRequest对象的支持度不足, 创建 XMLHttpRequest 对象时需要对IE浏览器做的兼
容解决。 - ActiveXObject
回顾:XHR
参考代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- </head>
- <body>
- <div id="app"></div>
- </body>
- <script>
- // 1.生成XHR对象
- var xhr = new XMLHttpRequest()
- // 2.绑定回调函数
- xhr.onreadystatechange = function () {
- // 3. 判断是否成功
- if (xhr.readyState === 4 && xhr.status === 200) {
- const list = JSON.parse(xhr.responseText).data
- console.log(list)
- }
- }
- // 4. 打开请求
- xhr.open('GET', 'https://api.i-lynn.cn/college')
- // 5.发送请求
- xhr.send()
- </script>
- </html>
jQuery类的引入解决自己写兼容的烦恼,但现在只是使用了jQuery库中的网络请求功能,而jQuery中大量的dom的方法都是无效引入了,有点大材小用的意思。
- $.ajax({
- url,
- type:get/post,
- data,
- dataType:json/text/xml/html/jsonp
- success:function(res){},
- error:function(){}
- })
- $.get(url,data,callback,dataType)
- $.post(url,data,callback,dataType)
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- </head>
- <body>
- <div id="app">
- <ul>
- <li v-for="(item,index) of list" :key = "index">{{ item.area }}</li>
- </ul>
- </div>
- </body>
- <script src="lib/jquery.min.js"></script>
- <script src="lib/vue.js"></script>
- <script>
- new Vue({
- el: '#app',
- data: {
- list: []
- },
- async mounted () {
- // async await
- // async 加载函数上,表示函数内部有异步操作
- // await 记载异步操作前,把异步操作写为同步
- const res = await $.get("https://api.i-lynn.cn/college", 'json')
- console.log(res)
- this.list = res.data.list
- }
- })
- </script>
- </html>
async:关键词,用于函数声明关键词 function 之前,标记当前的函数为异步函数
await:关键词,让当前关键词的行代码执行之后等到到结果之后再去执行后续代码
由HTML5提供的内置API
更加简单的数据获取方式,功能更强大、灵活,可以看作是xhr的升级版
基于Promise实现
fetch支持很多请求方式,但默认为 GET 请求,如果需要使用其他方式可以通过第二个自选参数的 method 选项去指定
- fetch(url[,some settings]).then(fn2) .then(fn3) ... .catch(fn)
- // 通过url表达式来传递数据
- fetch("http://xxx/?id=123")
- .then(res => res.json())
- .then(data => console.log(data));
-
- // post标准提交
- fetch("http://xxxx/post", {
- method: "post",
- body: "uname=lisi&pwd=123",
- headers: { "Content-Type": "application/x-www-form-urlencoded"
- }
- })
- .then(res => res.json())
- .then(data => console.log(data));
-
- // post提交json数据
- fetch("http://localhost:3000/books", {
- method: "post",
- body: JSON.stringify({ uname: "lisi", pwd: "123", }),
- headers: { "Content-Type": "application/json", }
- })
- .then(res => res.json())
- .then(data => console.log(data));
注意:fetch 不会发送 cookies。除非你使用了credentials 的初始化选项 credentials: "include"
在上述代码示例中我们会看到有个 json() 方法,它是fetch的响应结果处理方法,fetch的常用响应
结果处理方法有:
使用fetch方式改写 XHR 部分案例
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>06 fetch</title>
- </head>
- <body>
- <div id="app">
- <ul>
- <li v-for="item of list" :key="item.proid">
- {{ item.proname }}
- </li>
- </ul>
- <input type="text" v-model="loginname">
- <input type="text" v-model="password">
- <button @click="login">登录</button>
- </div>
- </body>
- <script src="lib/vue.js"></script>
- <script>
- new Vue({
- el: '#app',
- data: {
- list: [],
- loginname: '15635878563',
- password: '123456'
- },
- mounted () {
- // get请求
- fetch('http://182.44.11.110/api/pro/list?limitNum=1')
- .then(res => res.json()) // 需要把promise的对象转换为json对象
- .then(res => {
- console.log(res)
- this.list = res.data
- })
- },
- methods: {
- // post请求
- login () {
- fetch('http://http://182.44.11.110/api/user/login', {
- method: 'post',
- body: JSON.stringify({ loginname: this.loginname, password: this.password }),
- headers: {
- 'Content-Type': 'application/json'
- }
- }).then(res => res.json())
- .then(res => {
- console.log(res)
- })
- }
- }
- })
- </script>
- </html>
文档:https://www.kancloud.cn/yunye/axios/234845
axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和node.js中。axios是vue作者推荐使用
的网络请求库,它具有以下特性:
axios的浏览器支持
在使用axios之前需要在对应的模板文件中引入axios的js库文件,随后按照以下用法使用axios:
- // GET请求方式
- axios.get('/get_data?id=10010')
- .then(ret => console.log(ret.data))
-
- axios.get('/get_data',{
- params: {
- id: 10010,
- name: 'zhangsan',
- age: 26 } })
- .then(ret => console.log(ret.data))
-
- //POST请求方式
- axios.post('/set_data', {
- firstName: 'zhang', lastName: 'san'
- }).then(ret => { })
-
- axios({
- method: 'post',
- url: 'set_data',
- timeout: 1000,
- headers: {'X-Custom-Header': 'foobar'},
- data: { firstName: 'zhang', lastName: 'san' }
- }).then(ret => { })
当然axios除了支持传统的 GET 和 POST 方式以外,常见的请求方式还支持:
以上方的axios请求示例为例,axios响应结果( ret )的主要属性有:
另外需要注意的是,在使用axios发送请求之前它允许我们通过全局配置做一些设置,这样可以方便后续的请求操作,例如:
注意:
axios发送post请求的时候,默认发送json格式数据
如果需要发送post表单类型请求,则需要指定请求头
- axios.post('college',{
- username: 'zhangsan', age: 22
- },{
- headers: { "Content-Type": "application/x-www-form-urlencoded" }
- }).then(ret => this.list = ret.data.list)
使用axios方式改写 XHR 部分案例
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>07 axios</title>
- </head>
- <body>
- <div id="app">
- <ul>
- <li v-for="item of list" :key="item.proid">
- {{ item.proname }}
- </li>
- </ul>
- <input type="text" v-model="loginname">
- <input type="text" v-model="password">
- <button @click="login">登录</button>
- </div>
- </body>
- <script src="lib/vue.js"></script>
- <script src="lib/axios.min.js"></script>
- <script>
- // http://121.89.205.189/apidoc/
- new Vue({
- el: '#app',
- data: {
- list: [],
- loginname: '18813007814',
- password: '123456'
- },
- mounted () {
- // get请求
- // fetch('http://182.44.11.110/api/pro/list?limitNum=1')
- // .then(res => res.json()) // 需要把promise的对象转换为json对象
- // .then(res => {
- // console.log(res)
- // this.list = res.data
- // })
- // axios.get('http://182.44.11.110/api/pro/list')
- // .then(res => {
- // console.log(res)
- // this.list = res.data.data
- // })
- // axios.get('http://182.44.11.110/api/pro/list?limitNum=2')
- // .then(res => {
- // console.log(res)
- // this.list = res.data.data
- // })
- axios.get('http://182.44.11.110/api/pro/list', { // 推荐使用他传递参数
- params: {
- limitNum: 3
- }
- })
- .then(res => {
- console.log(res)
- this.list = res.data.data
- })
- },
- methods: {
- // post请求
- login () {
- // fetch('http://182.44.11.110/api/user/login', {
- // method: 'post',
- // body: JSON.stringify({ loginname: this.loginname, password: this.password }),
- // headers: {
- // 'Content-Type': 'application/json'
- // }
- // }).then(res => res.json())
- // .then(res => {
- // console.log(res)
- // })
- axios.post('http://182.44.11.110/api/user/login', {
- loginname: this.loginname,
- password: this.password
- }).then(res => {
- console.log(res)
- })
- }
- }
- })
- </script>
- </html>
目的:在请求 发出去之前 / 收到响应之后 做一些操作
请求拦截器
- axios.interceptors.request.use(function(config){
- // 在请求发出去之前进行一些信息设置
- return config;
- },function(err){
- // 处理响应的错误信息
- });
响应拦截器
- axios.interceptors.response.use(function(res){
- // res为axios对象
- return res;
- },function(err){
- // 处理响应的错误信息
- });
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- </head>
- <body>
- <div id="app">
- <ul>
- <li v-for="(item,index) of list" :key = "index">{{ item.area }}</li>
- </ul>
- </div>
- </body>
- <script src="lib/vue.js"></script>
- <script src="lib/axios.min.js"></script>
- <script>
- axios.interceptors.request.use(function(config){
- // 在请求发出去之前进行一些信息设置
- console.log('loading......')
- return config;
- },function(err){
- // 处理响应的错误信息
- });
-
- axios.interceptors.response.use(function(res){
- // res为axios对象
- console.log('loading end')
- return res;
- },function(err){
- // 处理响应的错误信息
- });
- new Vue({
- el: '#app',
- data: {
- list: []
- },
- mounted () {
- // axios.get('https://api.i-lynn.cn/college')
- // .then(res => {
- // console.log(res)
- // this.list = res.data.data.list
- // })
- axios({
- url: 'https://api.i-lynn.cn/college',
- method: 'GET',
- headers: {
- 'content-type': 'application/json'
- }
- }).then(res => {
- console.log(res)
- this.list = res.data.data.list
- })
- }
- })
- </script>
- </html>
通过本文的介绍,我们从最基础的 XMLHttpRequest 逐步过渡到了现代的 Axios,每一种请求方式都有其独特的优势和适用场景。XMLHttpRequest 虽然历史悠久,但依然在某些场景下有其价值;jQuery 简化了兼容性问题,但引入了额外的库;fetch 是原生的现代 API,简洁且功能强大;Axios 则是 Vue 官方推荐的库,支持 Promise,使用起来非常方便。希望本文能帮助你在实际项目中选择合适的网络请求方式。