ajax 及 fetch API详解

  1. XMLHttpRequest

     const xhr = new XMLHttpRequest(); xhr.open('GET', 'http://domain/serivce'); // 须要留神的是 在申请发送前建设对状态的监听 有可能申请响应十分快,状态监听还没有实现 xhr.onreadystatechange = function (){        if(xhr.readyState !== 4){         return;     }     if(xhr.status === 200){         console.log(xhr.responseText)     }else{         console.error(`HTTP error, status=${xhr.status},errorText=${xhr.statusText}`);     } } // 超时 xhr.timeout = 3000; xhr.ontimeout = () => {     console.log('以后申请超时啦') } // 文件上传进度 xhr.upload.onprogress = p => {     const precent = Math.round((p.loaded / p.total) * 100) + '%'; } xhr.send();
  2. fetch
  • 默认不带cookie
  • 谬误不会reject
  • 不反对超时设置
  • 须要通过AbortController终止fetch
    fetch('http://domain/serivce', {        method: 'GET',        credentials: 'same-origin',  // omit: 默认 不带cookie same-origin:同域携带cookie  include:即可同域携带,也可跨域携带    }).then(response => {        if(response.ok){            // 申请胜利            return response.json;        }        throw new Error('http error');    }).then(json => {        console.log(json)    }).catch(error => {        //  接管整体fetch谬误   throw new Error谬误        console.log(error);    })

封装一个fetch 超时

    function fetchTimeout(url, init, timeout = 3000){        return new Promise((resolve, reject) => {            fetch(url, init).then(resolve).catch(reject);            setTimeout(reject, timeout);        })    }    // 尝试一下:封装一个通用的异步函数的超时    // function (fn, timeout){ }

中断fetch

    const controller = new AbortController();    fetch('http://domain/serivce', {        method: 'GET',        credentials: 'same-origin',        siginal: controller.siginal    }).then(response => {        if(response.ok){            // 申请胜利            return response.json;        }        throw new Error('http error');    }).then(json => {        console.log(json)    }).catch(error => {        console.log(error);    })    // 勾销    // 会中断所有 controller.siginal 的 fetch    controller.abort();

常见的浏览器申请/响应头/错误码解析

request header

method
path

cookie

referer: 判断浏览器来自哪个页面,标识拜访门路
user-angent:常常用来判断各种各样的环境,比方做投放业务

response header

access-control-allow-origin: 制订具体域名 或者 * 不做限度
content-encoding: gzip
set-cookie

status

200 get 胜利
201 post 胜利
301 永恒重定向
302 长期重定向
304 协商缓存 服务器文件未修改
400 客户端申请有语法错误,不能被服务器辨认
403 服务器受到申请,然而回绝提供服务,可能是跨域
404 申请的资源不存在
405 申请的method不容许
500 服务器产生不可预期的谬误

强缓存
max-age 毫秒数,接管cookie多少毫秒后生效
expired 代表什么时候过期,工夫扭转之后cookie有效性会产生偏差

协商缓存
last-modified 判断以后文件是否被批改 毛病:在服务器关上不作任何批改last-modified还是会扭转
eTag 把整体文件内容进行了hash判断文件是否有过批改 更加准确 然而更加耗费性能

问:为什么常见的 cdn 域名和业务域名不一样?

<!-- www.baidu.com -->
<!-- cdn.baidu-aa.com -->

  1. 平安问题 cookie 携带了身份信息,域名雷同的话会把不必要的用户信息传给cdn厂商,公司不想裸露
  2. cdn request header 会携带 cookie ,无畏的减少了更多的带宽占用、资源耗费

问:常见的vue react spa利用,都会存在index.html文件,也就是所谓的单页,针对index.html要做缓存的话,适宜做什么缓存?

如果肯定要做的话,协商缓存。
spa利用的html文件非常简单,可能基本没有什么内容,编译产出的script css文件会变成 script link标签插入html外面,而这些文件自身是有hash命名的,是为了避免js css的缓存,然而index.html是没有hash的。
js文件更新十分频繁,如果做了强缓存,更新不能实时下发到用户端上去;如果做了协商缓存,每次打包文件都会产生扭转,就能够失常拉去更新代码。
失常的的话是 no-cache no-store

发送申请的示例,以及封装一个多浏览器兼容的申请函数

interface IOption{    url: string,    type?: 'GET' | 'POST',    data: any,    timeout?: number}function formatUrl(object){    const dataArr = [];    for(let key in object){        dataArr.push(`${key}=${encodeURIComponent(object[key])}`)    }    return dataArr.join('&');}export function ajax(options: IOption = {    url: '',    type: 'GET',    data: {},    timeout: 3000}) {    return new Promise((resolve, reject) => {        if(!options.url){            return ;        }        const queystring = formatUrl(options.data);        let timer;        let xhr;        const onStateChange = () => {            xhr.onreadystatechange = () => {                if(xhr.readyState === 4){                    if(xhr.status >= 200 && xhr.status <= 300 || xhr.status === 304){                        resolve(xhr.responseText);                    }else{                        reject(xhr.status);                    }                }            }        }        if((window as any).XMLHttpRequest){            xhr = new XMLHttpRequest();        }else{            xhr = new ActiveXObject("Microsoft.XMLHTTP");        }        if(options.type.toLowerCase() === 'GET'){            xhr.open('GET', `${options.url}?${queystring}`);            xhr.send();        }else if(options.type.toLowerCase() === 'POST'){            xhr.open('POST', options.url);            xhr.setRequestHeader(                'ContentType', 'application/json'            )            xhr.send(options.data);        }        if(options.timeout){            timer = setTimeout(() => {                xhr.abort();                reject('timeout')            }, options.timeout)        }    })}