這裡記錄工作中遇到的技術點,以及自己對生活的一些思考,周三或周五釋出。
封面圖
前端監控主要監控的内容有幾個方面:js錯誤,request請求,用使用者行為以及相關性能名額。
對于request請求的監控,主要監控的時間點在于
發起請求時
以及
收到請求時
兩個時間節點。在發起請求時,我們可以擷取到請求的方法,位址資訊。在收到請求時,我們可以計算請求花費的時長等我們想要的資訊。
用什麼技術點
XMLHttpRequest
想要實作對請求的監控,需要我們的對頁面中的請求進行攔截。
界面中的請求通常使用
XMLHttpRequest
對象發送請求,即便我們使用了諸如
axios
的庫,其内部的實作方式也是對
XMLHttpRequest
進行封裝,以簡化我們的請求操作,是以在正式開始之前我們需要對
XMLHttpRequest
常用的屬性和方法有一個簡單的了解。
-
XMLHttpRequest.open(method, url, async, user, password )
。
這個方法用來初始化一個請求。通過這個方法,我們可以擷取到請求的method, url, async, user, password資訊。
-
XMLHttpRequest.send()
。
這個方法用來發送一個請求。如果是異步請求(預設為異步請求),則此方法會在請求發送後立即傳回;如果是同步請求,則此方法直到響應到達後才會傳回。
想要監聽到相應的内容,需要我們對能夠接收到響應的資料。需要我們了解下面兩個事件。
-
load
事件。
當一個XMLHttpRequest請求完成的時候會觸發
事件。我們可以給load
對象添加load事件以監控請求結果。比如:XMLHttpRequest
const addListener = (xhr) => {
xhr.addEventListener('load', (msg)=>{console.log(msg)});
}
const http= (method,url)=>{
let xhr = new XMLhttpRequest();
addListener(xhr)
xhr.open(method,url)
xhr.send()
}
-
error
事件。
當請求遇到錯誤時,将觸發
事件。和error
事件一樣,我們可以監聽load
對象的load事件以監控請求錯誤資訊。示例:XMLHttpRequest
const addListener = (xhr) => {
xhr.addEventListener('error', (msg)=>{console.log(msg)});
}
const http= (method,url)=>{
let xhr = new XMLhttpRequest();
addListener(xhr)
xhr.open(method,url)
xhr.send()
}
了解了這幾個方法,足夠我們對request請求一個簡單的監控。
實作方式
在具體實施上,其原理就是對這些方法進行劫持,或者重寫。
實作的方式之一就是重寫
XMLHttpRequest
對象上的方法,使之具有擷取以及上報資料的能力。比如,這裡使用console将發送請求的相關資訊列印出來。
let orignOpen = XMLHttpRequest.prototype.open
function Fopen (method,url,async,username,password){
console.log('request info need report-----',method,url,async,username,password)
orignOpen.call(this,method,url,async,username,password)
}
XMLHttpRequest.prototype.open = Fopen
此時,我們執行代碼。然後發起請求,就可以看到我們想要的資訊。
我這裡是用node模拟了一個登入接口。
相比于使用自己定義方法來重寫
open
方法,我們也可以使用
proxy
來對它做一層代理,不管我們用什麼方法,本質上都是對open方法進行一層包裝,使它可以列印,收集到我們想要的資訊。
比如:
export const resetOpen2 = () => {
const handler = {
apply:function(target,thisArg,argumentsList){
console.log('thisArg',thisArg)
console.log('argumentsList',argumentsList)
return target.call(thisArg,argumentsList[0],argumentsList[1])
}
}
XMLHttpRequest.prototype.open = new Proxy(XMLHttpRequest.prototype.open,handler)
}
調用
resetOpen2
方法,我們就可以監聽到請求的方法以及請求的URL位址等資訊。
同理,我們可以使用
proxy
對send方法進行重寫,使它可以監聽send方法。
export const resetSend = () => {
const handleSendResule = (res)=> {
console.log('send-res',res)
}
const handler = {
apply:function(target,thisArg,body){
thisArg.addEventListener('load',handleSendResule)
thisArg.addEventListener('error',handleSendResule)
return target.call(thisArg,body)
}
}
XMLHttpRequest.prototype.send = new Proxy(XMLHttpRequest.prototype.send,handler)
}
結果如下:
這樣,我們就可以簡單的對
XMLHttpRequest
進行一定程度的監控。但是,僅僅能夠監控還是不夠的,我們需要對請求時間進行計算。
怎麼計算呢? 需要我們有一個比較好的方法。
先寫到這裡吧,明天繼續...
最後
這篇僅僅對
XMLHttpRequest
的監控方法做一個簡單的實作,後面會接着分析相關的問題。
未完待續...