使用拦截器处理 Ionic App 中的离线数据

Handling offline data in a Ionic App using an interceptor

那么一点背景知识,我有这个项目并且正在开发涉及添加离线功能的版本 2。我坚持使用以下堆栈,因为现在更改它会涉及很多开销:

Laravel API MYSQL 离子

我听说过很多关于使用 Pouch/CouchDB 进行同步的信息,但遗憾的是我无法更改所有内容以使用此堆栈。

我决定以我有限的 AngularJS/JS 知识使用 HTTP 拦截器拦截所有请求,检查它是否是 POST/PUT 请求,检查设备是否是 on/offline 或者将数据保存在本地存储或继续请求。这是问题开始的地方。

这是我的API拦截器:

App.factory('APIInterceptor', function ($q) {

    return {
        request: function (config) {

            if(config.method == 'POST' || config.method == 'PUT')
            {
                //Add data to localstorage

                //Exit without actually sending the request to the server.
                return $q.reject();
            }

            return config || $q.when(config);
        }
    };
});

如您所见,我正在返回 .reject(),但我需要的是模仿 API 响应并传回我的服务,就像请求已成功处理一样,以便我的应用程序可以继续运行普通的。本质上返回成功,状态码200数据存储到localstorage后

关于我如何做到这一点有什么建议吗?

创建一个管理所有 http 请求并最终 return 您的数据库数据的服务不是更容易吗?

Interceptors

For purposes of global error handling, authentication, or any kind of synchronous or asynchronous pre-processing of request or postprocessing of responses, it is desirable to be able to intercept requests before they are handed to the server and responses before they are handed over to the application code that initiated these requests. The interceptors leverage the promise APIs to fulfill this need for both synchronous and asynchronous pre-processing.

我猜你不需要检查设备是否 online/offline 因为你会在拦截器中得到一个 requestError

因为你想在通信实际发生之前拦截它,你可以使用这种拦截器:

.factory('APIInterceptor', function APIInterceptor($q) {
    return {
            request: function (config) {
                if(config.method == 'POST' || config.method == 'PUT')
                {
                    return $q.reject({status: 503, config: config});
                }
                return config || $q.when(config);
            },

            // response: function (httpResponse)
            // {
            //     return httpResponse || $q.when(httpResponse);
            // },

            responseError: function (rejection)
            {
                if (rejection.status === 503) {
                    rejection.status = 200;
                    rejection.statusText = "OK";
                    rejection.data = {};
                    return $q.resolve(rejection);
                }
                return $q.reject(rejection);
            }
        };
});

如果请求是 POSTPUT 你可以拒​​绝它添加状态并传递配置:

if(config.method == 'POST' || config.method == 'PUT')
{
    return $q.reject({status: 503, config: config});
}

responseError 将被处理。
现在您可以检查您的状态并解决承诺,以便您的 $http 调用不会捕获异常:

if (rejection.status === 503) {
    rejection.status = 200;
    rejection.statusText = "OK";
    rejection.data = {};
    return $q.resolve(rejection);
}

我附加了一个 data 对象,因为这是您的 http 调用可能期望的。 基本上,我们在这里所做的是尝试重新创建正确的响应。