在不同的文件/函数中捕获axios请求

时间:2018-04-03 17:33:11

标签: javascript vue.js exception-handling axios es6-promise

我使用HTTP请求来获取我的Vue.js应用程序的数据。我有一个名为 Api.js 的文件,带有基础axios实例:

export default () => {
  return axios.create({
    baseURL: apiURL,
    headers: {
      Authorization: `JWT ${store.state.token}`
    }
  })
}

我的文件名为 service.js ,其中包含不同端点的函数:

export default {
  status() {
    return Api().get('status/')
  }
}

.vue 文件中,我调用了这样的方法。

created() {
  Service.status()
    .then(response => {
      // do something with the data
    })
    .catch(e => {
      // show exception
    })
}

一些例外应该在 Api.js 中处理(例如:401),其他一些例外应该在 service.js 中的其他例外处理.vue 文件。我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

免责声明:我已经创建了两个小型axios插件,可以轻松实现这种特定模式。

axios-middleware

  

简单的axios HTTP中间件服务,以简化通过Axios进行的HTTP请求挂钩。

它使用axios拦截器作为mentioned by acdcjunior,但它使用公知的中间件模式抽象出axios的使用,因此您的应用程序不需要知道和处理拦截器语法。

<%= f.select :female_founder_eq, Company.female_founders.to_a, {prompt: "Any", selected: { true => 1, false => 0 }[@q.base[:female_founder_eq].try(:value)] } %>

然后,您可以使用此中间件服务在应用中的任何位置注册不同的中间件。中间件可以像对象一样简单,也可以是可重用,易于测试的类。

// import your API's axios instance
import http from './api';
import { Service } from 'axios-middleware';

// Create a new service instance
const service = new Service(http);

// We're good to go!
export default service;

import i18n from './services/i18n'; import toast from './services/toast'; import service from './services/middleware'; import { ApiErrorMiddleware, OtherMiddleware } from './middlewares'; // Then register your middleware instances. service.register([ // Middleware class instance new ApiErrorMiddleware(i18n, toast), new OtherMiddleware(), // or a simple object { onRequest() { // handle the request }, onResponseError(error) { // handle the response error } } ]); 将是一个简单的类,其中唯一的责任是在出错时显示Toast消息。

ApiErrorMiddleware

axios-resource

  

简单的axios资源类,可以轻松地与REST端点进行交互。

定义资源类。在此,我添加了export default class ApiErrorMiddleware { /** * @param {VueI18n} i18n instance * @param {Object} toast message service */ constructor(i18n, toast) { this.toast = toast; this.i18n = i18n; } /** * @param {Object} error */ onResponseError(error = {}) { const { response } = error; let key = 'errors.default'; if (response && this.i18n.te(`errors.${response.status}`)) { key = `errors.${response.status}`; } else if (error.message === 'Network Error') { key = 'errors.network-error'; } else { // TODO log unhandled errors } this.toast.error(this.i18n.t(key)); } } onError作为您的用例示例。

onFetchError

然后,在import Resource from 'axios-resource'; export default class UserResource extends Resource { static URL = 'user/{id}'; // This calls `sync` in the background fetch() { return super.fetch.apply(this, arguments) .catch(err => this.onFetchError(err)); } onFetchError(err) { // An error occurred while fetching this resource. } onError(err) { // An error occurred with this resource } // called for every actions (fetch, create, patch, delete) sync() { return super.sync.apply(this, arguments) .catch((err) => this.onError(err)) } } 中,创建一个实例。

api.js

每一步都可以处理错误。

  1. 在此特定资源的import UserResource from './user'; const user = new UserResource(); // GET https://example.com/api/user/me user.fetch('me') .then(({ data }) => { console.log('User data:', data); });
  2. 在此资源的onFetchError
  3. 在应用程序的中间件中。

答案 1 :(得分:0)

您应该添加axios interceptors

  

Axios拦截器

     

您可以在处理请求或响应之前拦截它们   thencatch

     
// Add a request interceptor
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
    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
    return response;
  }, function (error) {
    // Do something with response error
    return Promise.reject(error);
  });

那些可以(应该)在你的 Api.js