当前位置: 首页 > Web前端 > JavaScript

浏览器相关——浏览器请求

时间:2023-03-26 23:44:44 JavaScript

ajax和fetchAPI详解XMLHttpRequestconstxhr=newXMLHttpRequest();xhr.open('GET','http://domain/serivce');//注意在Establishingastatusmonitorbeforesendtherequest可能会请求一个非常快的响应,而状态监听还没有完成xhr.onreadystatechange=function(){if(xhr.readyState!==4){return;}if(xhr.status===200){console.log(xhr.responseText)}else{console.error(`HTTP错误,status=${xhr.status},errorText=${xhr.statusText}`);}}//超时xhr.timeout=3000;xhr.ontimeout=()=>{console.log('当前请求超时')}//文件上传进度xhr.upload.onprogress=p=>{constprecent=Math.round((p.loaded/p.total)*100)+'%';}xhr.send();fetch默认没有cookie报错不会reject不支持超时设置,fetch需要通过AbortController终止fetch('http://domain/serivce',{method:'GET',credentials:'same-origin',//省略:默认不带cookieok){//请求成功返回response.j儿子;}thrownewError('http错误');}).then(json=>{console.log(json)}).catch(error=>{//接收整体获取错误thrownewErrorerrorconsole.log(error);})封装了一个获取超时函数fetchTimeout(url,init,timeout=3000){returnnewPromise((resolve,reject)=>{fetch(url,init).then(resolve).catch(reject);setTimeout(reject,timeout);})}//尝试一下:用超时包装一个通用异步函数//function(fn,timeout){}abortfetchconstcontroller=newAbortController();fetch('http://domain/serivce',{method:'GET',credentials:'same-origin',signal:controller.signal}).then(response=>{if(response.ok){//请求成功returnresponse.json;}thrownewError('httperror');}).then(json=>{console.log(json)}).catch(error=>{console.log(error);})//cancel//会中断所有控制器.signal的获取controller.abort();常见的浏览器请求/响应头/错误码解析请求头methodpathcookiereferer:判断浏览器来自哪个页面,识别访问路径user-agent:常用于判断各种环境,例如发起业务响应头access-control-allow-origin:指定特定域名或*无限制content-encoding:gzipset-cookiestatus200获取成功201发布成功301永久重定向302临时重定向304协商缓存服务器文件未修改400客户403服务器收到请求,但拒绝提供服务,可能是跨域的404请求的资源不存在405请求的方法不允许500服务器发生意外错误Strongcachemax-agemilliseconds,收到cookie后多少毫秒,expired是什么时候过期,cookie的有效性会随着时间的变化而发生偏差。协商缓存last-modified判断当前文件是否被修改缺点:打开服务器不做任何修改last-modified仍然会改变eTag作为一个整体文件的内容进行hash判断文件是否被修改,这更准确但消耗更多的性能。Q:为什么普通CDN域名和企业域名不一样?安全问题cookie携带身份信息,如果域名相同,会向cdn厂商发送不必要的用户信息,公司不想暴露会携带cookies的cdn请求头,不怕增加更多的带宽和资源消耗。Q:常见的vuereactspa应用都会有一个index.html文件,也就是所谓的单页,需要对index.html做缓存,什么样的缓存合适?如果必须这样做,请协商缓存spa应用的html文件非常简单,可能根本就没有内容。编译后的scriptcss文件会变成一个scriptlink标签插入到html中,这些文件本身都是用hash命名的,防止jscss缓存,而index.html是没有hash的。js文件更新非常频繁。如果实现了强缓存,则无法将更新实时发送到客户端;如果实现协商缓存,每次打包后的文件都会发生变化,代码可以正常更新。Normal是一个no-cacheno-store发送请求的例子,封装了一个多浏览器兼容的请求函数接口IOption{url:string,type?:'GET'|'POST',data:any,timeout?:number}functionformatUrl(object){constdataArr=[];for(letkeyinobject){dataArr.push(`${key}=${encodeURIComponent(object[key])}`)}returndataArr.join('&');}导出函数ajax(options:IOption={url:'',type:'GET',data:{},timeout:3000}){returnnewPromise((resolve,reject)=>{if(!options.url){return;}constquerystring=formatUrl(options.data);lettimer;letxhr;constonStateChange=()=>{xhr.onreadystatechange=()=>{if(xhr.readyState===4){timer&&clearTimeout(timer)if(xhr.status>=200&&xhr.status<=300||xhr.status===304){resolve(xhr.responseText);}else{拒绝(xhr.status);}}}}if((任何窗口).XMLHttpRequest){xhr=newXMLHttpRequest();}else{xhr=newActiveXObject("Microsoft.XMLHTTP");}if(options.type.toLowerCase()==='GET'){xhr.open('GET',`${options.url}?${queystring}`);onStateChange();xhr.发送();}elseif(options.type.toLowerCase()==='POST'){xhr.open('POST',options.url);onStateChange();xhr.setRequestHeader('ContentType','application/json')xhr.send(options.data);}if(options.timeout){timer=setTimeout(()=>{xhr.abort();reject('timeout')},options.timeout)}})}