使用axios对API请求保持干燥

HTTP请求是与后端服务器通信的任何Web应用程序的关键部分。 前端需要一些数据,因此它通过网络HTTP请求(或Ajax,因为它通常被称为)来请求数据,然后服务器返回答案。 如今,几乎每个网站都以某种方式进行此操作。

如果站点更大,我们可以期望看到更多。 更多数据,更多API和更多特殊情况。 随着网站的发展,保持组织有序很重要。 一个经典的概念是DRY(Don(不要重复自己)的缩写),它是抽象代码以防止一遍又一遍重复的过程。 之所以理想,是因为它通常允许我们编写一次内容,在多个地方使用它,然后在一个地方而不是每个实例中进行更新。

我们还可以联系图书馆来帮助我们。 对于Ajax, axios是一种流行的选择。 您可能已经很熟悉它,甚至在开发过程中甚至将其用于独立的POST和GET请求。

安装和基础

可以使用npm(或yarn)安装它:

npm install axios

使用Axios的独立POST请求如下所示:

axios.post('https://axios-app.firebaseio.com/users.json', formData)
  .then(res => console.log(res))
  .catch(error => console.log(error))

原生JavaScript也有多种执行JavaScript的方法。 值得注意的是, fetch() 。 那么为什么要完全使用一个库呢? 好吧,其中之一是,获取中的错误处理非常糟糕。 有了axios,您会度过一个美好的时光。 如果您想比较一下,我们有一篇文章涵盖了这两者还有一篇文章讨论了类似这样的东西的抽象价值

接触axios的另一个原因? 它为我们提供了更多的DRYness机会,因此让我们来研究一下。

全局配置

我们可以使用通过axios附带的默认对象设置的标准配置 ,来设置处理所有应用程序请求的全局配置(例如,在main.js文件中)。

该对象包含:

  • baseURL:相对URL,充当所有请求的前缀,每个请求都可以附加URL
  • headers可以根据请求设置的自定义标头
  • timeout:中止请求的timeout:点,通常以毫秒为单位。 默认值为0 ,表示不适用。
  • withCredentials指示是否应使用凭据发出跨站点访问控制请求。 默认值为false
  • responseType指示服务器将返回的数据类型,包括json (默认), arraybuffe r, documenttextstream
  • responseEncoding指示用于解码响应的编码。 默认值为utf8
  • xsrfCookieName用作XSRF令牌的值的cookie名称,默认值为XSRF-TOKEN
  • xsrfHeaderName带有XSRF令牌值的HTTP标头的名称。 默认值为X-XSRF-TOKEN
  • maxContentLength以允许的字节数定义HTTP响应内容的最大大小
  • maxBodyLength以允许的字节数定义HTTP请求内容的最大大小

大多数时候,您只会使用baseURLheader ,甚至可能使用timeout 。 由于它们具有智能默认值,因此较少需要它们,但是很高兴知道那里有需要修复的请求。

这就是工作中的干燥度。 对于每个请求,我们不必重复我们API的baseURL或重复每个请求中可能需要的重要标头。

这是一个示例,其中我们的API有一个基础,但它也有多个不同的端点。 首先,我们设置一些默认值:

// main.js
import axios from 'axios';


axios.defaults.baseURL = 'https://axios-app.firebaseio.com' // the prefix of the URL
axios.defaults.headers.get['Accept'] = 'application/json'   // default header for all get request
axios.defaults.headers.post['Accept'] = 'application/json'  // default header for all POST request


Then, in a component, we can use axios more succinctly, not needing to set those headers, but still having an opportunity to customize the final URL endpoint:


// form.js component
import axios from 'axios';


export default {
  methods : {
    onSubmit () {
      // The URL is now https://axios-app.firebaseio.com/users.json
      axios.post('/users.json', formData)
        .then(res => console.log(res))
        .catch(error => console.log(error))
    }
  }
}

注意:此示例在Vue中,但是该概念扩展到了任何JavaScript情况。

自订执行个体

设置“自定义实例”类似于全局配置,但范围仅限于指定的组件。 因此,它仍然是DRY技术,但是具有层次结构。

我们将在一个新文件中设置自定义实例(我们将其authAxios.js )并将其导入“关注”组件中。

// authAxios.js
import axios from 'axios'


const customInstance = axios.create ({
  baseURL : 'https://axios-app.firebaseio.com'
})
customInstance.defaults.headers.post['Accept'] = 'application/json'


// Or like this...
const customInstance = axios.create ({
  baseURL : 'https://axios-app.firebaseio.com',
  headers: {'Accept': 'application/json'}
})

然后,我们将此文件导入到表单组件中:

// form.js component


// import from our custom instance
import axios from './authAxios'


export default {
  methods : {
    onSubmit () {
      axios.post('/users.json', formData)
      .then(res => console.log(res))
      .catch(error => console.log(error))
    }
  }
}

拦截器

在全局配置或自定义实例可能过于通用的情况下,如果您在它们的对象内设置了头文件,则拦截器会提供帮助,它适用于受影响组件内每个请求的头文件。 拦截器具有即时更改任何对象属性的能力。 例如,我们可以根据在拦截器中选择的任何条件发送不同的标头(即使我们已经在对象中设置了标头)。

拦截器可以位于main.js文件或自定义实例文件中。 发送请求后将对其进行拦截,并允许我们更改响应的处理方式。

// Add a request interceptor
axios.interceptors.request.use(function (config) {
  // Do something before request is sent, like we're inserting a timeout for only requests with a particular baseURL
  if (config.baseURL === 'https://axios-app.firebaseio.com/users.json') { 
    config.timeout = 4000 
  } else { 
    return config
  }
  console.log (config)
    return config;
  }, function (error) {
  // Do something with request error
  return Promise.reject(error);
});
 
// Add a response interceptor
axios.interceptors.response.use(function (response) {
  // Do something with response data like console.log, change header, or as we did here just added a conditional behaviour, to change the route or pop up an alert box, based on the reponse status  
  if (response.status === 200 || response.status 201) {
    router.replace('homepage') }
  else {
    alert('Unusual behaviour')
  }
  console.log(response)
  return response;
}, function (error) {
  // Do something with response error
  return Promise.reject(error);
});

顾名思义,拦截器会拦截请求和响应,以根据提供的任何条件采取不同的行动。 例如,在上面的请求拦截器中,仅当请求具有特定的baseURL ,我们才插入条件超时。 对于响应,我们可以拦截它并修改返回的内容,例如更改路线或设置一个警报框,具体取决于状态码。 我们甚至可以根据不同的错误代码提供多个条件。

随着项目的扩大,拦截器将变得非常有用,并且您将开始拥有大量路由和嵌套路由,这些路由和嵌套路由都基于不同的触发器与服务器进行通信。 除了我上面设定的条件之外,根据您的项目,还有许多其他情况可以保证使用拦截器。

有趣的是,我们可以弹出一个拦截器,以使其完全不起作用。 我们必须将拦截器分配给变量,然后使用适当命名的eject方法将其eject

const reqInterceptor = axios.interceptors.request.use(function (config) {
  // Do something before request is sent, like we're inserting a timeout for only requests with a particular baseURL
  if (config.baseURL === 'https://axios-app.firebaseio.com/users.json') {
    config.timeout = 4000
  } else {
    return config
  }
  console.log (config)
  return config;
}, function (error) {    
  // Do something with request error
  return Promise.reject(error);
});
 
// Add a response interceptor
const resInterceptor = axios.interceptors.response.use(function (response) {
  // Do something with response data like console.log, change header, or as we did here just added a conditional behaviour, to change the route or pop up an alert box, based on the reponse status  
  if (response.status === 200 || response.status 201) {
    router.replace('homepage')
  } else {
    alert('Unusual behaviour')
  }
  console.log(response)
  return response;
}, function (error) {
  // Do something with response error
  return Promise.reject(error);
});


axios.interceptors.request.eject(reqInterceptor);
axios.interceptors.request.eject(resInterceptor);

尽管不那么常用,但可以将拦截器放入条件语句中,也可以根据某些事件将其删除。


希望这可以使您对axios的工作方式以及如何将其保持在应用程序中的API请求保持干燥状态有个好主意。 尽管我们通过介绍常见的用例和配置来摸索表面,但是axis还有许多其他优点可以在文档中探索,包括取消请求和防止跨站点请求伪造的能力,以及其他令人敬畏的可能性。

翻译自: https://css-tricks.com/stay-dry-using-axios-for-api-requests/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值