与服务端通信——axios

与服务端通信——axios

在实际项目中,页面所需要的数据通常是从服务端获取的,这必然牵涉与服务端的通信,Vue官方推荐使用axios完成Ajax请求。axios是一个基于Promise的HTTP库,可以用在浏览器和Node.js中。

安装

可以使用CDN方式安装:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

如果采用模块化开发,则使用npm安装方式:

npm install axios --save

在vue的脚手架项目中使用,可以将axios结合vue-axios插件一起使用,该插件只是将axios集成到Vue.js的轻度封装,本身不能独立使用。可以使用以下命令安装:

npm install axios vue-axios

安装vue-axios插件后,使用形式如下:

import {createApp} from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
​
const app = createApp(App);
app.use(VueAxios,axios)   //安装插件
app.mount('#app')

之后在组件内就可以通过this.axios调用axios的方法发送请求。

基本用法

HTTP最基本的请求就是get和post。使用axios发送get请求调用形式如下:

axios.get('/book?id=1')
    .then(function(response) {
        console.log(response);
    })
    .catch(function(error) {
        console.log(error);
    })

get方法接收一个URL作为参数,如果有要发送的数据,则以查询字符串的形式附加在URL后面。当服务端发回成功响应(状态码是2XX)时调用then()方法中的回调,可以在该回调函数中对服务端的响应进行处理;如果出现错误则会调用catch中的回调,可以在该回调函数中对错误信息进行处理,并向用户提示错误。

如果不喜欢URL后附加查询参数的写法,可以为get方法传递一个配置对象作为参数,在配置对象中使用params字段指定要发送的数据:

axios.get('/book',{
    params:{
        id:1
    }
})
.then(function(response) {
        console.log(response);
    })
    .catch(function(error) {
        console.log(error);
    })

可以使用ES2017的async/await执行异步请求:

async function getBook(){
    try {
        const response = await axios.get('/book?id=1');
        console.log(response);
    } catch(error){
        console.error(error);
    }
} 

post请求是在请求体中发送数据,因此,axios的post方法比get方法多一个参数,该参数是一个对象,对象的属性就是要发送的数据:

axios.post('/login',{
    username:'lisi',
    password:'1234'
})
.then(function(response){
    console.log(response);
})
.catch(function(error) {
    console.log(error);
});

get()和post()方法的原型如下:

get(url[,config])
post(url[,data[,config]])

接收到服务端的响应信息后,需要对响应信息进行处理。例如,设置用于组件渲染或更新所需要的数据。回调函数中的response是一个对象,该对象常用的属性是data和status,前者用于获取服务端发回的响应数据,后者是服务端发送的HTTP状态代码。

response对象的完整属性:

{
    //data是服务器发回的响应数据
    data:{},
    //服务器响应的状态码
    status:200,
    //状态描述
    statusText:'OK',
    //headers是服务器响应的消息报头,所有报头的名字都是小写的
    //可以通过response.headers['content-type']
    headers:{},
    //config是为请求提供的配置信息
    config:{},
    //request是生成此响应的请求
    request:{}
}

成功响应后,获取数据的一般处理形式如下:

axios.get('/book?id=1')
  .then(function(response){
    if(response.status === 200) {
        this.book = response.data;
    }
})
.catch(function(error) {
    console.log(error);
});

如果出现错误则会调用catch方法中的回调,并向该回调函数传递一个错误对象。错误对象的一般形式如下:

axios.get('/book?id=1')
  .catch(function(error) {
    if (error.response) {
        //请求已发送并接收到服务端响应,但响应的状态码不是2XX
        console.log(error.response.data);
        console.log(error.response.status);
        console.log(error.response.headers);
    } else if (error.request) {
        //请求已发送,但未接收到响应
        console.log(error.request);
    } else {
        //在设置请求时出现问题而引发错误
        console.log('Error',error.message);
    }
    console.log(error.config);
});

axios API

可以通过向axios传递相关配置来创建请求。axios原型如下:

axios(config)
axios(url[,config])

get请求和post请求的调用形式如下:

//发送get请求(默认的方法)
axios('/book?id=1');
//get请求,获取远端的图片
axios({
    method:'get',
    url:'/images/logo.png',
    responseType:'stream'
})
  .then(function(response) {
    response.data.pipe(fs.createWriteStream('logo.png'))
});
​
//发送post请求
axios({
    method:'post',
    url:'/login',
    data:{
        username:'lisi',
        password:'1234'
    }
});

为了方便使用,axios库为所有支持的请求方法提供了别名:

  • axios.request(config)

  • axios.get(url[,config])

  • axios.delete(url[,config])

  • axios.head(url[,config])

  • axios.options(url[.config])

  • axios.post(url[,data[,config]])

  • axios.put(url[,data[,config]])

  • axios.patch(url[,data[,config]])

在使用别名方法时,url、method、data这些属性都不必在配置对象中指定。

请求配置

axios库为请求提供了配置对象,在该对象中可以设置很多选项,常用的是url、method、headers和params:

{
    url:'/book',
    method:'get',
    //baseURL将自动加在url前面,除非url是一个绝对URL
    //为axios实例设置一个baseURL就可以将相对URL传递给该实例的方法
    baseURL:'https://some-domain.com/api/',
    //transformRequest允许在将请求数据发送到服务器前对其修改
    //只能用于put、post、patch、delete这几个请求方法
    //数组中的最后一个函数必须返回一个字符串、Buffer的实例、ArrayBuffer、FormData或Stream
    //也可以修改headers对象
    transformRequest:[function(data,headers) {
        //对data进行任意转换处理
        return data;
    }],
    
    //transformResponse允许在将响应数据传递给then/catch之前对其修改
    transformResponse:[function(data) {
        //对data进行任意转换处理
        return data;
    }],
    
    //是要发送的自定义请求头
    headers:{'X-Requested-With':'XMLHttpRequest'},
    
    params:{
        ID:1
    },
        
    //是一个负责params序列化的可选函数
    paramsSerializer:function(params) {
        return Qs.stringify(params,{arrayFormat:'brackets'})
    }
    
    data:{
        firstName:'Fred'
    },
    //只发送值,不发送键
    data:'Country=Brasil&City=Belo',
        
    timeout:1000,//请求超过timeout则终止
    
    withCredentials:false,  //默认值,表示跨域请求时是否需要凭证
        
    //adapter允许自定义处理请求,以使测试更加容易
    //返回一个promise并提供一个有效的响应
    adapter:function(config) {
        ...
    },
    
    //auth表示应该使用HTTP基础验证,并提供凭据
    //这将设置一个Authorization报头,覆盖使用headers设置的现有的Authorization自定义报头
    auth:{
        username:'zzd',
        password:'1234'
    }
        
    responseType:'json',   //默认的,响应的数据类型
        
    responseEncoding:'utf8'  //解码响应数据的编码
    ...
}

并发请求

有时需要同时向服务端发起多个请求,这可以用Promise.all实现,例如:

function getUserAccount() {
    return axios.get('/user/12345');
}
function getUserPermissions() {
    return axios.get('/user/12345/permissions');
}
Promise.all([getUserAccount(),getUserPermissions()])
.than(function(results) {
    //两个请求现在都执行完成
    const acct = result[0];  //响应结果1
    const perm = result[1];  //响应结果2
})

创建实例

可以使用自定义配置调用axios.create([config])方法创建一个axios实例,之后使用该实例向服务端发起请求,就不用每次请求时重复设置配置选项了:

const instance = axios.create({
    baseURL:'https://some-domain.com/api/',
    timeout:1000,
    headers:{
         'X-Custom-Header':'foobar'
    }
})

配置默认值

对于每次请求相同的配置选项,可以通过为配置选项设置默认值来简化代码的编写。项目中用的全局axios默认值可以在项目的入口文件main.js中按照以下形式设置:

axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.withCredentials = true

也可以在自定义实例中设置配置默认值,这些配置选项只有在使用该实例发起请求时才生效:

//创建实例时设置配置默认值
const instance = axios.create({
    baseURL:'http://api.example.com'
});
//实例创建后更改默认值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

配置将按优先顺序进行合并。顺序是在lib/defaults.js中找到的库的默认值,然后是实例的defaults属性,最后是请求的config参数。后者将优先于前者。

var instance = axios.create();
instance.default.timeout = 2500;
instance.get('/longRequest'.{
             timeout:5000
             })

拦截器

有时需要统一处理HTTP的请求和响应,如登录验证,这时就可以使用axios的拦截器,分为请求拦截器和响应拦截器,他们会在请求或响应被then()或catch()方法处理前拦截它们。axios的拦截器的使用形式如下:

//添加请求拦截器
axios.interceptors.request.use(function(config) {
    //在请求发送前做些什么
    return config;
}, function (error) {
    //对请求错误做些什么
    return Promise.reject(error);
});
​
//添加响应拦截器
axios.interceptors.response.use(function(response) {
    //在响应数据做些什么
    return response;
}, function (error) {
    //对请求错误做些什么
    return Promise.reject(error);
});

前面章节使用全局守卫实现了一个用户登录验证的例子,不过这种方式只是简单的前端路由控制,用户一旦登录成功,前端就保存了用户登录的状态,允许用户访问受保护的资源。如果在这期间,该用户在服务端失效了,比如用户长时间未操作、服务端强制下线、或者管理员将该用户拉入黑名单,那么前端就应该及时更新用户的状态,对用户的后续访问做出控制。在这种情况下,就应该使用axios的拦截器结合HTTP状态码进行用户是否已登录的判断:

//请求拦截器
axios.interceptors.request.use(
    config => {
        if (token) {
            //判断是否存在token,如果存在,则每个HTTP header都加上token
            config.headers.Authorization = `token ${store.state.token}`;
        }
        return config;
    },
    err => {
        return Promise.reject(err);
    });
​
//响应拦截器
axios.interceptors.response.use(
    response => {
        return response;
    },
    error => {
        if (error.response) {
            switch (error.response.status) {
                case 401:
                    //如果返回401,则清除token信息并跳转到登录页面
                    router.replace({
                        path:'login',
                        query:{redirect:router.currentRoute.fullPath}
                    })
            }
        }
        return Promise.reject(error.response.data)
    });

如果之后想移除拦截器,则可以:

const myInterceptor = axios.interceptors.request.use(function(){...});
axios.interceptors.request.eject(myInterceptor);

也可以为自定义的axios实例添加拦截器:

const instance = axios.create();
instance.interceptors.request.use(function(){});

  • 25
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Node.js中使用axios请求接口以及拦截器的使用方法如下: 首先,需要安装axios模块: ``` npm install axios ``` 然后,在代码中引入axios模块: ```js const axios = require('axios'); ``` 接下来,可以使用axios发送GET、POST等请求: ```js axios.get('http://example.com/api') .then(response => { console.log(response.data); }) .catch(error => { console.log(error); }); axios.post('http://example.com/api', {data: 'hello'}) .then(response => { console.log(response.data); }) .catch(error => { console.log(error); }); ``` 当然,axios还支持一些其他的请求方法,比如PUT、DELETE等。 接下来,我们可以使用axios的拦截器对请求和响应进行处理。例如,我们可以在请求头中添加token: ```js axios.interceptors.request.use(config => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, error => { return Promise.reject(error); }); ``` 在上面的代码中,我们使用了axios的interceptors.request.use方法,它可以在请求被发送出去之前对其进行拦截处理。在这个例子中,我们将localStorage中存储的token添加到请求头中的Authorization字段中。 我们还可以使用axios的interceptors.response.use方法对响应进行处理。例如,我们可以检查响应状态码是否为401,如果是,则跳转到登录页面: ```js axios.interceptors.response.use(response => { return response; }, error => { if (error.response.status === 401) { window.location.href = '/login'; } return Promise.reject(error); }); ``` 在上面的代码中,我们使用了axios的interceptors.response.use方法,它可以在响应被接收之前对其进行拦截处理。在这个例子中,我们检查了响应状态码是否为401,并且在这种情况下跳转到登录页面。 以上就是在Node.js中使用axios请求接口及拦截器的使用方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值