免责声明:我创建了两个小型 axios 插件来轻松实现这种特定模式。
简单的 axios HTTP 中间件服务,用于简化对通过 Axios 发出的 HTTP 请求的挂钩。
它使用 axios 拦截器作为 mentioned by acdcjunior,但它使用众所周知的中间件模式抽象了 axios 的使用,因此您的应用不需要了解和处理拦截器语法。
// 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
}
}
]);
ApiErrorMiddleware 是一个简单的类,仅负责在错误时显示 toast 消息。
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));
}
}
简单的 axios 资源类,可轻松与 REST 端点交互。
定义一个资源类。在这里,我添加了 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 中创建一个实例。
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);
});
可以在每一步处理错误。
- 在此特定资源的
onFetchError 中
- 在此资源的
onError 中
- 在应用的中间件中。