截取JavaScript中的fetch()API请求和响应
我想截取JavaScript中的获取API请求和响应 例如,在发送请求之前,我想截取请求URL。我也希望在响应到达后拦截它 下面的代码用于截取所有截取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
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)=>…
跳过生活。这是稳定性的最佳答案