跳到主要内容

网络请求监控与上报

2024年04月21日
柏拉文
越努力,越幸运

一、认识


Web 监控 SDK 一般通过以下两种方式网络请求进行上报:

const originFetch = window.fetch;
window.fetch = (...args)=>{
console.log("Fetch", args[0]);
return originFetch(...args);
}
const open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url){
console.log("XMLHttpRequest:", url);
open.apply(this, arguments);
}

通过对于运行时 sandbox 的了解, 可以非常容易的代理 fetchXMLHttpRequest 的请求操作从而收集请求地址, 通过收集的网络请求进行分发上报

class fakeXMLHttpRequest extends XMLHttpRequest{
constructor(){
super();
}

open(){
sandbox.sourceList.push({
tagName: "xmlhttprequest",
url: arguments[1]
});

return super.open.apply(this, arguments);
}

abort(){
xhrSet.delete(this);
return super.abort.apply(this, arguments);
}
}

const fakeFetch = (input, options: RequestInit = {})=>{
sourceList.push({ tagName: 'fetch', url: input });
return window.fetch(input, options);
}
const fn = new Function('XMLHttpRequest', 'fetch', `
fetch('https://api.example.com/data', { method: 'GET' })
.then(response=> response.json());

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data',true);
xhr.onload = function(){
console.log(data);
}
xhr.onerror = function (){
console.error('XMLHttpRequest failed', xhr.status, xhr.statusText);
}
xhr.send();
`);

fn(fakeXMLRequest, fakeFetch);