jQuery中的ajax

jQuery中的ajax

jquery中的ajax

API:别人调用我我能返回东西的就叫api。向这个url发送请求服务器能返回东西的就叫api

demo:

const xhr=new XMLHttpRequest();
console.log(xhr.readyState);
xhr.open('GET','https://mock.mengxuegu.com/mock/6262c4510a65bd50bbd93eee/cgi/list');
console.log(xhr.readyState);
// 超时
xhr.onreadystatechange=function(){
    console.log('==='+xhr.readyState);
    if(!(/^(2|3)\d{2}$/.test(xhr.status))) return;
    if(xhr.readyState===4){
        console.log('===done')
        console.log(xhr.responseText)
    }
}
xhr.send();
console.dir(xhr);

用别人现成的封装好的库来实现——ajax

$.ajax

c1708befea3312910a7d86950d108da3.png

配置项:

1f7117570430aa07594f848a72c0d8fe.png

contentType

传递给服务器内容的格式

这里有一个概念要区分一下,类型一般是字符串(除了字符串就是真正的流传输了)。而字符串下有好多种格式。

常用的格式:

x-www-form-urlencoded: get/post 默认遵循的都是这种格式

heades:

设置请求头

$.ajax({
    url:'https://mock.mengxuegu.com/mock/6262c4510a65bd50bbd93eee/cgi/list',
    method:'GET',
    data:{
        name:'angela',
        age:18,
    },
    cache:false,
    success:(res,status,xhr)=>{
        console.log(res);
        console.log(status);
        console.log(xhr);
    }
})

倒计时抢购案例

从服务器获取时间一定会存在误差问题:

服务器把时间给我到我拿到这个时间,中间经历的时间,就是时差

/**
 * 1.首次从服务器获取时间
 * 2.然后interval没间隔1秒计算时差
 */


function ajaxTime(callback){
    let xhr=new XMLHttpRequest();
    xhr.open('GET','https://mock.mengxuegu.com/mock/6262c4510a65bd50bbd93eee/cgi/list');
    xhr.setRequestHeader('Access-Control-Expose-Headers', 'Date');
    xhr.onreadystatechange=function(){
        if(xhr.readyState===2){
            now=new Date(xhr.getResponseHeader('Date'));
            callback && callback();
        }
    }
    xhr.send();
};
let target=new Date('2022/4/23 24:00:00')
let timer=null;
let now=null;


function computed(){
    console.log(now);
    let spanTime=target-now;
    if(spanTime<=0){
        clearInterval(timer);
        timer=null;
        return;
    }
    // 计算时分秒
    let spanSecond=spanTime/1000;
    console.log(spanSecond);
    let hours=Math.floor(spanSecond/3600);
    let minutes=Math.floor((spanSecond-hours*3600)/60);
    let seconds=spanSecond%60;
    document.getElementById('hour').innerHTML=hours;
    document.getElementById('minute').innerHTML=minutes;
    document.getElementById('second').innerHTML=seconds;
    // 加一秒钟
    now=new Date(+now+1000)
}
ajaxTime(()=>{
    computed();
    window.setInterval(computed,1000);
})

封装jquery版的ajax

封装组件、插件、类库,都是基于构造函数来做的。

所有类库/插件的封装都是基于构造函数,面向对象、类和实例、构造函数在业务开发中用不到,构造函数用于组件、类库和插件的封装上,包括框架的封装。

类的方法:

当做普通函数来执行,但是也然能创建出它的一个实例来;

绕了一圈。jQuery是类但是把它当做普通函数执行也能创建出它的实例

ajax

/**
 * jquery版本
 * 弊端:相互循环调用
 */


(function(){
    function ajax(options){
        // return ajax.prototype.fn.init(options) 
        return ajax.prototype.init(options)
    }
    ajax.prototype={
        constructor:ajax,
        version:1,
    }
    ajax.prototype.init=function init(options){}
    ajax.prototype.init.prototype=ajax.prototype;


    window.ajax=ajax;


})();


简单版:

/**
 * 简单版本
 */


(function(){
    function ajax(options){
        return new init(options)
    }
     ajax.prototype={
        constructor:ajax,
        version:1,
    }


    function init(options){


    }
    init.prototype=ajax.prototype;


    window.ajax=ajax;


})();


自己封装

  1. 配置项初始化

Object.assign 目标对象中出现的字段无条件覆盖。只要这个字段出现了,就会覆盖原来的。

那init是个类,之后所有方法都要用到options,那么需要把options挂在实例上。

封装的时候这里有一个扩展的点:函数的3种角色

(function(){
    function ajax(options){
        return new init(options)
    }


    let defaults={
        url:'',
        method:'GET',
        data:null,
        dataType:'JSON',
        async:true,
        cache:true,
        headers:null,
        timeout:null,
        success:null,
        error:null,
    }
    function init(options){
        // 配置参数
        this.options=Object.assign(defaults,options);
        this.send();
    }
    ajax.prototype={
        constructor:ajax,
        version:1,
        send(){


        }
    }
    init.prototype=ajax.prototype;


    window.ajax=ajax;






})();


  1. xhr ajax请求

handleData

(function(){
    function ajax(options){
        return new init(options)
    }


    let defaults={
        url:'',
        method:'GET',
        data:null,
        dataType:'JSON',
        async:true,
        cache:true,
        headers:null,
        timeout:null,
        success:null,
        error:null,
    }
    function init(options){
        // 配置参数
        this.options=Object.assign(defaults,options);
        this.xhr=null;
        this.send();
    }
    let regGET=/^(GET)|(DELETE)|(HEAD)|(OPTIONS)$/i
    ajax.prototype={
        constructor:ajax,
        version:1,
        send(){
            let xhr=null;
            this.xhr=xhr=new XMLHttpRequest;
            let {url,method,data,cache}=this.options;
            // 这里的判断要扩展一下
            // if(method==='GET'){
            //     // url+='?'
            //     // if(!url.endsWith('/')){
            //     //     url+='/'
            //     // }
            //     // 尝试把这一段封装成一个方法
            //     if(typeof data ==='string'){
            //         url+=`?${data}`
            //     }
            //     if(typeof data === 'object'){
            //         url+=`?${Object.entries(data).map(a=>`${a[0]}=${a[1]}`).join('&')}`
            //     }
            // }
            data=this.handleData();
            if(data!==null && regGET.test(method)){
                url+=`${this.checkAsk(url)}${data}`;
                data=null;
            }
            // 把cache处理掉了
            if(!cache && regGET.test(method)){
                url+=`${this.checkAsk(url)}_=${+new Date}`;
            }
            xhr.open(url,method)
        },
        // 这里封装得很好
        handleData(){
            let {data}=this.options;
            if(data === null || typeof data === 'string') return data;
            if(typeof data === 'object') return Object.entries(data).map(a=>`${a[0]}=${a[1]}`).join('&')
        },
        checkAsk(url){
            return url.includes('?')?'&':'?'
        }
        
    }
    
    init.prototype=ajax.prototype;


    window.ajax=ajax;


})();


timeout/headers

判类型:Object.prototype..call(headers)

(function(){
    function ajax(options){
        return new init(options)
    }


    let defaults={
        url:'',
        method:'GET',
        data:null,
        dataType:'JSON',
        async:true,
        cache:true,
        headers:null,
        timeout:null,
        success:null,
        error:null,
    }
    function init(options){
        // 配置参数
        this.options=Object.assign(defaults,options);
        this.xhr=null;
        this.send();
    }
    let regGET=/^(GET)|(DELETE)|(HEAD)|(OPTIONS)$/i
    ajax.prototype={
        constructor:ajax,
        version:1,
        send(){
            let xhr=null;
            this.xhr=xhr=new XMLHttpRequest;
            let {url,method,data,cache,timeout,headers}=this.options;
            data=this.handleData();
            if(data!==null && regGET.test(method)){
                url+=`${this.checkAsk(url)}${data}`;
                data=null;
            }
            // 把cache处理掉了
            if(!cache && regGET.test(method)){
                url+=`${this.checkAsk(url)}_=${+new Date}`;
            }
            xhr.open(url,method)
            // 设置超时时间
            timeout!==null?xhr.timeout=timeout:null;
            // 设置header
            if(Object.prototype.toString.call(headers)==='[object Object]'){
                Object.keys(headers).forEach(key=>{
                    xhr.setRequestHeader(key,headers[key]);
                })
            }
            xhr.send(data);
        },
        // 这里封装得很好
        handleData(){
            let {data}=this.options;
            if(data === null || typeof data === 'string') return data;
            if(typeof data === 'object') return Object.entries(data).map(a=>`${a[0]}=${a[1]}`).join('&')
        },
        checkAsk(url){
            return url.includes('?')?'&':'?'
        }
        
    }
    
    init.prototype=ajax.prototype;
    window.ajax=ajax;


})();


success/error

(function(){
    function ajax(options){
        return new init(options)
    }


    let defaults={
        url:'',
        method:'GET',
        data:null,
        dataType:'JSON',
        async:true,
        cache:true,
        headers:null,
        timeout:null,
        success:null,
        error:null,
    }
    function init(options){
        // 配置参数
        this.options=Object.assign(defaults,options);
        this.xhr=null;
        this.send();
    }
    let regGET=/^(GET)|(DELETE)|(HEAD)|(OPTIONS)$/i
    ajax.prototype={
        constructor:ajax,
        version:1,
        send(){
            let xhr=null;
            this.xhr=xhr=new XMLHttpRequest;
            let {url,method,data,cache,timeout,headers,async}=this.options;
            data=this.handleData();
            if(data!==null && regGET.test(method)){
                url+=`${this.checkAsk(url)}${data}`;
                data=null;
            }
            // 把cache处理掉了
            if(!cache && regGET.test(method)){
                url+=`${this.checkAsk(url)}_=${+new Date}`;
            }
            xhr.open(method,url,async)
            // 设置超时时间
            timeout!==null?xhr.timeout=timeout:null;
            // 设置header
            if(Object.prototype.toString.call(headers)==='[object Object]'){
                Object.keys(headers).forEach(key=>{
                    xhr.setRequestHeader(key,headers[key]);
                })
            }
            let {success,error,dataType}=this.options;
            xhr.onreadystatechange=()=>{
                let { readyState,status,statusText,responseText,responseXML}=xhr;
                if(readyState===4 && /^(2|3)\d{2}$/.test(status)){
                    switch(dataType.toUpperCase()){
                        case 'JSON':
                            responseText=JSON.parse(responseText);
                        break;
                        case 'XML':
                            responseText=responseXML;
                        break;
                    }
                    success && success(responseText,statusText,xhr);
                    return;
                }
                error && error(statusText,xhr);
                
            }
            xhr.send(data);
        },
        // 这里封装得很好
        handleData(){
            let {data}=this.options;
            if(data === null || typeof data === 'string') return data;
            if(typeof data === 'object') return Object.entries(data).map(a=>`${a[0]}=${a[1]}`).join('&')
        },
        checkAsk(url){
            return url.includes('?')?'&':'?'
        }
        
    }
    
    init.prototype=ajax.prototype;


    window.ajax=ajax;






})();
ajax({
    url:'https://mock.mengxuegu.com/mock/6262c4510a65bd50bbd93eee/cgi/list',
    success:(obj)=>{
        console.log('obj===');
        console.log(obj);
    },
    headers:{
        a:'a',
    },
    data:{
        name:'a',
    }
})
(function(){
    function ajax(options){
        return new init(options)
    }


    let defaults={
        url:'',
        method:'GET',
        data:null,
        dataType:'JSON',
        async:true,
        cache:true,
        headers:null,
        timeout:null,
        success:null,
        error:null,
    }
    function init(options){
        // 配置参数
        this.options=Object.assign(defaults,options);
        this.xhr=null;
        this.send();
    }
    let regGET=/^(GET)|(DELETE)|(HEAD)|(OPTIONS)$/i
    ajax.prototype={
        constructor:ajax,
        version:1,
        send(){
            let xhr=null;
            this.xhr=xhr=new XMLHttpRequest;
            let {url,method,data,cache,timeout,headers,async}=this.options;
            data=this.handleData();
            if(data!==null && regGET.test(method)){
                url+=`${this.checkAsk(url)}${data}`;
                data=null;
            }
            // 把cache处理掉了
            if(!cache && regGET.test(method)){
                url+=`${this.checkAsk(url)}_=${+new Date}`;
            }
            xhr.open(method,url,async)
            // 设置超时时间
            timeout!==null?xhr.timeout=timeout:null;
            // 设置header
            if(Object.prototype.toString.call(headers)==='[object Object]'){
                Object.keys(headers).forEach(key=>{
                    xhr.setRequestHeader(key,headers[key]);
                })
            }
            let {success,error,dataType}=this.options;
            xhr.onreadystatechange=()=>{
                let { readyState,status,statusText,responseText,responseXML}=xhr;
                if(readyState===4 && /^(2|3)\d{2}$/.test(status)){
                    switch(dataType.toUpperCase()){
                        case 'JSON':
                            responseText=JSON.parse(responseText);
                        break;
                        case 'XML':
                            responseText=responseXML;
                        break;
                    }
                    success && success(responseText,statusText,xhr);
                    return;
                }
                error && error(statusText,xhr);
                
            }
            xhr.send(data);
        },
        // 这里封装得很好
        handleData(){
            let {data}=this.options;
            if(data === null || typeof data === 'string') return data;
            if(typeof data === 'object') return Object.entries(data).map(a=>`${a[0]}=${a[1]}`).join('&')
        },
        checkAsk(url){
            return url.includes('?')?'&':'?'
        }
        
    }
    
    init.prototype=ajax.prototype;


    window.ajax=ajax;






})();
ajax({
    url:'https://mock.mengxuegu.com/mock/6262c4510a65bd50bbd93eee/cgi/list',
    success:(obj)=>{
        console.log('obj===');
        console.log(obj);
    },
    headers:{
        a:'a',
    },
    data:{
        name:'a',
    }
})


请求头Content-Type - 简书

HTTP请求头中的Content-Type类型 - 百度文库

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值