• XMLHttpRequest拦截请求和响应


    环境: angular
    实现: 拦截请求 向请求信息增加字段
                拦截响应 过滤返回值
    响应拦截:
    根据angular使用的XMLHttpRequest 将对原本的请求转移到另一个将监听返回事件挂载到另一个世纪发送请求的xml上
    使用get set 将客户端获取的responseText和response按照自己的意愿返回实现响应拦截

    请求拦截
    比较简单了 网上也比较常见
    修改send函数的参数即可

    核心代码

                const MyXMLHttpRequest = window.XMLHttpRequest;
                class InterceptXML extends window.XMLHttpRequest {
                    constructor(...p) {
                        super(...p);
                    }
    
                    addEventListener(t, fn) {
                        super.addEventListener(t, fn);
                    }
    
                    _statusText = "";
    
                    get statusText() {
                        return this._statusText || super.statusText;
                    }
    
                    set statusText(val) {
                        this._statusText = val;
                    }
    
                    _status = "";
    
                    get status() {
                        return this._status || super.status;
                    }
    
                    set status(val) {
                        this._status = val;
                    }
    
                    _response = "";
    
                    get response() {
                        return this._response || super.response;
                    }
    
                    set response(val) {
                        this._response = val;
                    }
    
                    _responseText = "";
    
                    get responseText() {
                        return this._responseText || super.responseText;
                    }
    
                    set responseText(val) {
                        this._responseText = val;
                    }
    
                    /**
                     * 完全覆盖 将原请求转移到另一个
                     */
                    cover(method, url) {
                        const xml = new MyXMLHttpRequest();
                        xml.open(method, url, true);
                        this.addEventListener = (type, callback) => {
                            if (type == "loadend") {
                                this.getAllResponseHeaders = () =>
                                    xml.getAllResponseHeaders();
    
                                xml.addEventListener(type, () => {
                                    this.statusText = xml.statusText;
                                    this.status = xml.status;
                                    this.response = xml.response;
                                    this.responseText = xml.responseText;
                                    console.log("拦截:", this.response);
                                    this.response = {data:['拦截了']};
                                    callback();
                                });
                            } else xml.addEventListener(type, callback);
                        };
    
                        this.setRequestHeader = (...r) =>
                            xml.setRequestHeader(...r);
                        this.send = () => xml.send();
                    }
    
                    afterRender(call) {
                        if (window.requestIdleCallback) {
                            requestIdleCallback(() => {
                                call();
                            });
                        } else if (window.requestAnimationFrame) {
                            requestAnimationFrame(() => {
                                requestAnimationFrame(() => {
                                    call();
                                });
                            });
                        } else {
                            setTimeout(() => {
                                call();
                            }, 32);
                        }
                    }
    
                    open(method, url) {
                        if (method === "GET" && url.includes('/todo')) {
                            return this.cover(method, url);
                        }
                    }
                }
    
                window.XMLHttpRequest = InterceptXML;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104

    以下代码为拦截get获取评论列表和post拦截发送请求业务代码 可供参考

    //匹配 发送评论请求路径
    const CommentReg = new RegExp(
        /\\/api\\/.+\\/.+\\/[0-9a-f]{24}\\/comment(\\/[0-9a-f]{24})*/
    );
    //匹配 获取评论列表请求路径
    const GetCommentsReg = new RegExp(
        /\\/api\\/.+\\/.+\\/[0-9a-f]{24}\\/comments*/
    );
    
    const MyXMLHttpRequest = window.XMLHttpRequest;
    
    class InterceptXML extends window.XMLHttpRequest {
        constructor(...p) {
            super(...p);
        }
    
        addEventListener(t, fn) {
            super.addEventListener(t, fn)
        }
    
        get hasInjectDom() {
            return document.getElementById("insertCheckBox")
        }
    
        _statusText = "";
        
        get statusText() {
            return this._statusText || super.statusText;
        }
    
        set statusText(val) {
            this._statusText = val;
        }
    
        _status = "";
    
        get status() {
            return this._status || super.status;
        }
    
        set status(val) {
            this._status = val;
        }
    
        
        _response = "";
    
        get response() {
            return this._response || super.response;
        }
    
        set response(val) {
            this._response = val;
        }
    
        
        _responseText = "";
    
        get responseText() {
            return this._responseText || super.responseText;
        }
    
        set responseText(val) {
            this._responseText = val;
        }
    
        
        cover(method, url) {
            const xml = new MyXMLHttpRequest();
            xml.open(method, url, true);
    
            this.addEventListener = (type,callback) => {
                if (type == 'load') {
                    this.getAllResponseHeaders = () => {
                        return xml.getAllResponseHeaders()
                    }
                    xml.addEventListener(type, () => {
                        this.statusText = xml.statusText;
                        this.status = xml.status;
                        this.response = xml.response;
                        this.responseText = xml.responseText;
                        callback()
                    })
                    // 处理dom
                    xml.addEventListener("loadend", () => {
                        requestAnimationFrame(() => {
                            requestAnimationFrame(() => {
                                
                            })
                        })
                    })
                }
                else xml.addEventListener(type,callback)
            }
    
            this.setRequestHeader = (...r) => {
                xml.setRequestHeader(...r)
            }
    
            this.send = () => {
                xml.send();
            }
        }
    
        open(method, url) {
            if (method === 'GET' && GetCommentsReg.test(url)) { 
               return this.cover(method, url);
            } else {
                if (["POST", "PUT","DELETE"].includes(method) && CommentReg.test(url) && this.hasInjectDom) {
                    const originalSend = super.send;
                    super.send = function (data) {
                        const modifiedData = Object.assign(
                            { is_private: window._is_private_comment || false },
                            JSON.parse(data)
                        );
                        originalSend.call(this,JSON.stringify(modifiedData));
                    };
                }
                super.open(method, url);
            }
        }
    }
    
    window.XMLHttpRequest = InterceptXML;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
  • 相关阅读:
    docker更新正在运行中的容器内存
    SpringMVC学习---第二课
    什么是Java的垃圾回收机制?
    什么样的应用程序适合使用Flutter开发桌面?
    DJ9-2 中断方式
    RabbitMQ发布确认高级
    分数限制下,选好专业还是选好学校?
    人工智能:支持向量机SVM 练习题(带解析)
    Ubuntu中设置代理的方式
    基于SSM的国学文化网站设计与实现
  • 原文地址:https://blog.csdn.net/printf_hello/article/details/134070665