Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
截取JavaScript中的fetch()API请求和响应_Javascript_Ajax_Xmlhttprequest_Interceptor_Fetch Api - Fatal编程技术网

截取JavaScript中的fetch()API请求和响应

截取JavaScript中的fetch()API请求和响应,javascript,ajax,xmlhttprequest,interceptor,fetch-api,Javascript,Ajax,Xmlhttprequest,Interceptor,Fetch Api,我想截取JavaScript中的获取API请求和响应 例如,在发送请求之前,我想截取请求URL。我也希望在响应到达后拦截它 下面的代码用于截取所有XMLHTTPRequests的响应 (function(open) { XMLHttpRequest.prototype.open = function(XMLHttpRequest) { var self = this; this.addEventListener("readystatechange", fu

我想截取JavaScript中的获取API请求和响应

例如,在发送请求之前,我想截取请求URL。我也希望在响应到达后拦截它

下面的代码用于截取所有
XMLHTTPRequest
s的响应

(function(open) {
  XMLHttpRequest.prototype.open = function(XMLHttpRequest) {
    var self = this;
    this.addEventListener("readystatechange", function() {
      if (this.responseText.length > 0 && 
          this.readyState == 4 && 
          this.responseURL.indexOf('www.google.com') >= 0) {

        Object.defineProperty(self, 'response', {
          get: function() { return bValue; },
          set: function(newValue) { bValue = newValue; },
          enumerable: true,
          configurable: true
        });
        self.response = 'updated value' // Intercepted Value 
      }
    }, false);
    open.apply(this, arguments);
  };
})(XMLHttpRequest.prototype.open);

我想为
fetch()
API实现相同的功能。我怎样才能做到这一点呢?

为了拦截获取请求和参数,我们可以采用下面提到的方法。这解决了我的问题

 const constantMock = window.fetch;
 window.fetch = function() {
     // Get the parameter in arguments
     // Intercept the parameter here 
    return constantMock.apply(this, arguments)
 }

为了拦截响应主体,您需要创建一个新的Promisse,并将当前解析或拒绝为“then”代码。它为我解决了问题,并为真正的应用程序保留内容。反应等

const constantMock = window.fetch;
 window.fetch = function() {
  console.log(arguments);

    return new Promise((resolve, reject) => {
        constantMock.apply(this, arguments)
            .then((response) => {
                if(response.url.indexOf("/me") > -1 && response.type != "cors"){
                    console.log(response);
                    // do something for specificconditions
                }
                resolve(response);
            })
            .catch((error) => {
                reject(response);
            })
    });
 }
const fetch=window.fetch;
window.fetch=(…args)=>(异步(args)=>{
var结果=等待获取(…参数);
console.log(result);//在此处截取响应
返回结果;
})(args);

继Hariharan的回答之后,下面是我如何在每次提取请求前后更新Redux中的微调器状态

import store from './../store';

// Set up interceptor on all fetch API calls
// Increments redux spinner state when api is called
// Decrements redux spinner state again when it is returned
(function() {
    const originalFetch = window.fetch;
    window.fetch = function() {
        store.dispatch({type: 'show-spinner'})
        return originalFetch.apply(this, arguments)
            .then((res) => {
                store.dispatch({type: 'hide-spinner'})
                return res;
            })
    }
})();

现有答案显示了浏览器中模拟
fetch
的一般结构,但忽略了重要的细节

显示了用自定义实现替换
窗口.fetch
函数的常规模式,该实现拦截调用并将参数转发给
fetch
。但是,所示的模式不允许拦截函数对响应执行任何操作(例如,读取状态或主体或注入模拟),因此只对记录请求参数有用。这是一个非常狭窄的用例

使用
async
函数让拦截器
fetch
上等待
,并可能处理响应(模拟、读取等),但(在编写时)有多余的闭包,并且没有显示如何以非破坏性方式读取响应体。它还包含一个导致堆栈溢出的变量别名错误

是迄今为止最完整的,但是回调中有一些无关的噪音,并且没有提到克隆响应以使主体能够被拦截器收集。它没有说明如何返回模拟

这里有一个最简单、完整的示例来纠正这些问题,展示了如何处理参数记录、在不损害原始调用方的情况下读取主体以及(可选)提供模拟响应

const{fetch:origFetch}=window;
window.fetch=async(…args)=>{
log(“用args调用的获取:”,args);
const response=wait origFetch(…args);
/*在单独的承诺中使用克隆响应
chain——可以使用与'await'相同的链*/
响应
.clone()
.json()
.then(body=>console.log(“截获的响应:”,body))
.catch(err=>console.error(err))
;
/*原始响应可以不经修改地解析:*/
//返回响应;
/*或者嘲笑回应:*/
返回{
好的,没错,
现状:200,
json:async()=>({
用户ID:1,
id:1,
标题:“嘲弄!!”,
已完成:false
})
};
};
//用一个典型的fetch调用来测试它
取回(“https://jsonplaceholder.typicode.com/todos/1")
.then(response=>response.json())
.then(json=>console.log(“收到的原始调用方:”,json))
.catch(err=>console.error(err))

;
听起来像是要侵入窗口。请求接口执行与问题中的代码示例类似的操作。我个人无法提供任何更具体的指导,然后说,这就是您可能想要开始试验的地方。有没有任何方法可以检测所有成功的fetch API调用回调?。例如:$(document).ajaxSuccess(函数(事件、xhr、设置){});检查响应状态的唯一方法是检查响应对象的
ok
属性:
fetch(someURL)
Thank you@sidehowbarker..我想为站点中的所有提取请求添加成功回调。我将在应用程序顶部运行我的代码。我不知道根据回调中的请求URL在应用程序中注册了多少提取请求,我需要执行一些功能。只想添加一个细节:如果需要响应body要“针对特定条件执行某些操作”,请不要忘记克隆响应,否则,承诺的最终用户将获得“TypeError:body已被使用”。因此,请执行“response.clone().json()”或“response.clone().text()”获取尸体。@Michael你是个救命恩人。这会毁掉Chrome 83.0中的堆栈。
const origFetch=window。fetch
wait origFetch(…args)
解决了这个问题。另外,我不确定最外层的函数为什么存在。你可以使用
fetch=async(…args)=>…
跳过生活。这是稳定性的最佳答案