拦截 Fetch 函数 - 请求 Headers

Intercepting Fetch function - Request Headers

我正在拦截已经拦截的获取,我无法读取最终请求数据(具体请求 headers)。

拦截我的意思是包装原始 window.fetch()

查看下面的评论。

// this was already wrapped before me...
// so it's NOT pure window.fetch
const originalFetch = window.fetch;
 
window.fetch = function() {
    
    // this will be added to the request
    arguments[1].headers.append("X-Security-A", 1);
    
    // After apply() below, the arguments are changed using
    // other external functions, which also intercept the fetch
    // and they will add additional headers;
    // I don't have access to these functions.
    
    // I cannot change the resource URL, because the external
    // functions check it.
    
    // I need to read the new headers, but the [arguments]
    // remain unchanged. They are changed somewhere within this apply()
    var promise = originalFetch.apply(this, arguments);
    
    // this will be added, but will NOT be added to actual
    // request, which already happened
    arguments[1].headers.append("X-Security-B", 1);
    
    promise.then((response) => {
        
            // Here I will get the results, but the request headers
            // are still NOT here;
            // only the ones I added
            // If I look in Chrome Console the sent request
            // contains all the headers I need to see.
            
            // HOW CAN I GET THE REQUEST HEADERS HERE?

            console.log('XXX Promise', promise);
            console.log('XXX Headers ', Array.from(arguments[1].headers.entries()));
            console.log('XXX Response', response);
            return response;
        });

    return promise;
}

好的,所以一旦 window.Fetch 被第二次包装,那么您将无法在实际请求之前获取最新的参数。

如果能做第一个包装就太完美了,但我的脚本最后一个运行。

但是可以拦截 prototype.call() 和 prototype.apply() 并且这对我有用:)

const originalFetch = window.fetch;
const originalCall = window.Function.prototype.call;

window.fetch = function() {
    
    var lastCall;
    window.Function.prototype.call = function(){
        lastCall = arguments;
        return originalCall.apply(this, arguments);
    };
    
    var x = originalFetch.apply(this, arguments);

    window.Function.prototype.call = originalCall; // reset
    
    x.then((response) => {
        
        console.log("XXX intercepted:", lastCall, response);
        
        return response;
    });
    
    return x;
};