整体架构设计项目地址【部分代码】注意点:1.xhr"rewrite"import{dispatch}from"../event";从“../listen/type”导入{AJAX_RESPONSE_TIME,AJAX_STATUS_ERROR};constxhrMdifiy=(options={witheList:[],})=>{//全局变量constwin=window;//标准ajaxconstXMLHttpRequest=win.XMLHttpRequest;//获取constfetch=win.fetch;//输出XMLconstOutXMLHttpRequest=function(){conststartTime=Date.now();constxhr=newXMLHttpRequest();常量自我=这个;constreadystatechangeEvent=[];constonerrorEvent=[];让身体=空;constrHeaders=[];让类型='';constcatchNormalRequestStatus=function(e){const{currentTarget}=e;const{response,responseURL}=currentTarget;constendTime=Date.now();if(xhr.readyState===XMLHttpRequest.DONE){if(xhr.status===200){letdiffTime=endTime-startTime;派遣(AJAX_RESPONSE_TIME,diffTime);}别的{constrequestHeaders=rHeaders.reduce((p,q)=>{return{...p,[q[0]]:q[1],};},{});if(typeofbody==="string"){body=body;}if(bodyinstanceofFormData){constbCopy={};for(letpairofformData.entries()){if(bCopy[1]instanceofBlob){bCopy[pair[0]]={fileName:bCopy[1].fileName,size:bCopy[1].size,};}else{bCopy[pair[0]]=pair[1];}}}if(bodyinstanceofBlob){constbCopy={};bCopy={文件名:body.fileName,size:body.size,};}if(bodyinstanceofObject){body=JSON.stringify(body);}constpostData={类型,正文,响应,responseURL,requestHeaders,}console.log(postData)dispatch(AJAX_STATUS_ERROR,postData);}}};//readystatechangeEvent.push(catchNormalRequestStatus);//代理xhr对象for(letkeyinxhr){if(["setRequestHeader","send",'open'].includes(key)){continue;}Object.defineProperty(self,key,{get(){if(typeofxhr[key]==="function"){returnxhr[key].bind(xhr);}returnxhr[key];},设置(arg){switch(key){case"onreadystatechange":{constfn=arg;fn&&readystatechangeEvent.push(fn);break;}默认:{xhr[key]=arg;}}},});}//重写为了获得请求类型self.open=function(...arg){type=arg[0]xhr.open.apply(xhr,arg)}//重写以获取发送数据self.send=function(data){body=data;xhr.发送(数据);};self.setRequestHeader=function(...arg){rHeaders.push(arg);xhr.setRequestHeader(...arg);};//检查状态变化[默认注入监听事件]xhr.onreadystatechange=function(e){readystatechangeEvent.forEach((fn)=>{if(typeoffn==="function"){fn.call(xhr,e);}});};回归自我;};win.XMLHttpRequest=OutXMLHttpRequest;};exportdefaultxhrMdifiy;2.资源加载和代码错误import{LOAD_SOURCE_ERROR,SCRIPT_EXECUTE_ERROR}from"../listen/type";import{dispatch,on}from"../event";import{event}from"@l6zt/cutils";constwin=window;constdoc=window.document;/*必须有【crossorigin="anonymous"】】*/event.on(win,'error',(e)=>{const{message,filename,lineno,colno,srcElement}=e;if(filename){constpayload={message,filename,lineno,colno,}console.log(payload)dispatch(SCRIPT_EXECUTE_ERROR,payload);}});//观察资源加载情况【观察文档“媒体元素”插入情况】constobserver=newMutationObserver((mutationsList,observer)=>{mutationsList.forEach((mutation)=>{const{type,addedNodes}=mutation;if(type==="childList"){addedNodes.forEach((el)=>{if([HTMLScriptElement,HTMLImageElement,HTMLVideoElement,HTMLAudioElement,Image].find((C)=>elinstanceofC))复制代码{event.on(el,'error',(e)=>{const{target}=e;constpayload={type:target.localName,src:target.getAttribute('src')||target.getAttribute('href')}console.log(payload)dispatch(LOAD_SOURCE_ERROR,payload)})}});}});});observer.observe(doc,{attributes:true,childList:true,subtree:true});3.性能监控【示例】constwin=windowwin.addEventListener('load',function(){constperfData=window.performance.timing;constpageLoadTime=perfData.loadEventEnd-perfData.navigationStart;constconnectTime=perfData.responseEnd-perfData.requestStart;constrenderTime=perfData.domComplete-perfData.domLoading;});
