您的位置:

Ajax-hook详解

Ajax-hook是一款非常方便的JS库,在前后端交互中起到了非常重要的作用。本文将从ajaxhook原理、ajaxhookjs、ajaxhook用法、ajaxhook使用示例、ajaxhook把请求挂起、ajaxhook全局加解密等多个方面对其进行详细的阐述。

一、ajaxhook原理

ajaxhook库可以通过拦截XMLHttpRequest对象来捕获前端HTTP请求,并再请求被发送前做出更改。其核心代码如下:

(function () {
    var XHR = XMLHttpRequest.prototype;
    var open = XHR.open;
    var send = XHR.send;
    ...
})();

上述代码通过重新定义XMLHttpRequest.prototype对象中的open、send两个方法,来将拦截到的HTTP请求进行修改处理。

二、ajaxhookjs

ajaxhookjs是一个能够将ajax-hook引入到项目中的JS文件。其使用方法非常简单,只需要在HTML的中添加下面代码即可:

<!-- ajaxhook.js -->
<script src="ajaxhook.js"></script>

三、ajaxhook用法

ajaxhook用法非常简单,只需要在需要拦截的请求前添加上hook即可:

function fn (ajax) {
    return function (data) {
        // Do something here
        return ajax.apply(this, arguments);
    };
}

// Hook jQuery's ajax method
$.ajax = fn($.ajax);

上述代码是通过拦截jQuery库中的ajax方法来进行示范的。其中fn函数用来对请求进行定制化的处理,如全局加解密等。然后将该函数注入ajax方法中,即可实现对所有请求的拦截效果。

四、ajaxhook使用示例

1、hook请求头

我们可以通过hook方法来修改请求头信息:

function fn (ajax) {
    return function (data) {
        // Do something here
        data.headers['Authorization'] = 'Bearer ' + token;  // 修改token信息
        return ajax.apply(this, arguments);
    };
}

// Hook jQuery's ajax method
$.ajax = fn($.ajax);

2、hook请求体

我们也可以通过hook方法来修改请求体:

function fn (ajax) {
    return function (data) {
        // Do something here
        data.data = encrypt(data.data);   // 数据加密
        return ajax.apply(this, arguments);
    };
}

// Hook jQuery's ajax method
$.ajax = fn($.ajax);

3、hook响应信息

还可以通过hook方法来对响应信息进行修改:

function fn (ajax) {
    return function (data) {
        // Do something here
        var defer = new $.Deferred();

        ajax(data).done(function (response) {
            response.result = decrypt(response.result);   // 解密响应信息
            defer.resolve(response);
        });

        return defer.promise();
    };
}

// Hook jQuery's ajax method
$.ajax = fn($.ajax);

五、ajaxhook把请求挂起

在某些时候,我们需要将异步请求挂起,等待其他异步操作完成之后再继续执行。使用ajaxhook,我们只需要在拦截到请求后,将请求挂起即可:

(function () {
    var XHR = XMLHttpRequest.prototype;
    var open = XHR.open;
    var send = XHR.send;

    XHR.open = function (method, url, async) {
        this._url = url;
        open.call(this, method, url, async);
    };

    XHR.send = function (data) {
        var _this = this;
        var oldOnReadyStateChange;
        var url = this._url;

        function onReadyStateChange() {
            if (this.readyState === 1) {
                var hookData = {method: _this._method, url: url, data: data};
                // Hook the request with the hook function
                hook(hookData, function () {
                    _this._data = hookData.data;
                    send.call(_this, _this._data);
                });

                oldOnReadyStateChange.apply(this, arguments);
            }
        }

        if (!this.addEventListener) {
            oldOnReadyStateChange = this.onreadystatechange;
            this.onreadystatechange = onReadyStateChange;
        } else {
            this.addEventListener("readystatechange", onReadyStateChange);
        }
    };
})();

上述代码中的hook函数中,我们可以实现将异步请求挂起,等待其他异步操作完成之后,再继续执行该请求。具体的操作方法详见以上代码实现。

六、ajaxhook全局加解密

在实际开发过程中,我们经常会需要对前端与后台交互的数据进行加解密操作,这时候我们可以使用ajaxhook来实现全局加解密。

首先,我们需要在请求体的hook方法中,将所有的请求数据进行加密操作:

function encryptData(data) {
    return CryptoJS.AES.encrypt(data, '123456').toString();  // 加密方式为AES加密
}

function fn (ajax) {
    return function (data) {
        data.data = encryptData(data.data);
        return ajax.apply(this, arguments);
}

然后,在响应信息的hook方法中,将所有返回的数据进行解密操作:

function decryptData(data) {
    return CryptoJS.AES.decrypt(data, '123456').toString(CryptoJS.enc.Utf8);
}

function fn (ajax) {
    return function (data) {
        var defer = new $.Deferred();

        ajax(data).done(function (response) {
            response.result = decryptData(response.result);
            defer.resolve(response);
       });

        return defer.promise();
    };
}

以上就是ajaxhook全局加解密的实现方法。我们可以在项目中,将加解密方法进行封装,然后在请求和响应的hook方法中统一调用,实现全局加解密的效果。