如何发请求?

用 form 可以发请求,但是会刷新页面或新开页面

用 a 可以发 get 请求,但是也会刷新页面或新开页面

用 img 可以发 get 请求,但是只能以图片的形式展示

用 link 可以发 get 请求,但是只能以 CSS、favicon 的形式展示

用 script 可以发 get 请求,但是只能以脚本的形式运行

有没有什么方式可以实现:

  • get、post、put、delete 请求都行

  • 想以什么形式展示就以什么形式展示

有!这就是今天要讲的 Ajax。

同源策略

只有 协议+端口+域名 一模一样才允许发 AJAX 请求

http://baidu.com 不可以向 http://www.baidu.com 发 AJAX 请求

http://baidu.com:80 不可以向 http://baidu.com:81 发 AJAX 请求

浏览器必须保证只有 协议+端口+域名 一模一样才允许发 AJAX 请求

但 CORS 可以告诉浏览器,我俩一家的,别阻止他

Ajax 可以设置任意请求 header

第一部分:request.open(‘get’,’/xxx’)

第二部分:request.setHeader(‘content-type’,’x-www-form-urlencoded’)

第四部分:request.send(‘a=1&b=2’)

Ajax 可以获取任意响应 header

第一部分:request.status / request.statusText

第二部分:request.getResponseHeader() / request.getAllResponseHeaders()

第四部分:request.respondText

Ajax

Ajax 示例:

let request = new XMLHttpRequest()
request.open('get', '/xxx')
request.send()
request.onreadystatechange = ()=>{
    if(request.readyState === 4){ 
        if(request.status >= 200 && request.status < 300){
            console.log('说明请求成功')
        }else if(request.status >= 400){
            console.log('说明请求失败') 
        }
    }
}

自制 jQuery.Ajax

window.jQuery.ajax = (url, method, body, success, fail)=>{
    let request = new XMLHttpRequest()
    request.open(method, url)
    request.send(body)
    request.onreadystatechange = ()=>{
        if(request.readyState === 4){
            if(request.status === 200){
                success.call(undefined,request.statusText)
            }else{
                fail.call(undefined,request.statusText)
            }
        }
    }

}

function success(e){
    console.log(e)
}

function fail(e){
    console.log(e)
}

myButton.addEventListener('click', ()=>{
    jQuery.ajax('/xxx','get',null,success,fail)
})

自制 jQuery.Ajax( Promise 版本)

回调的问题是每个程序员的回调名不一样

Promise 解决了这个问题

Promise 示例:

function xxx(){
    return new Promise((f1, f2) => {
        doSomething()
        setTimeout(()=>{
            // 成功就调用 f1,失败就调用 f2
        },3000)
    })
}

xxx().then(success, fail)

// 链式操作
xxx().then(success, fail).then(success, fail)

自制 jQuery.Ajax( Promise 版本):

window.jQuery.ajax = ({url, method, body})=>{
    return new Promise(function(resolve, reject){
        let request = new XMLHttpRequest()
        request.open(method, url)
        request.send(body)
        request.onreadystatechange = ()=>{
            if(request.readyState === 4){
                if(request.status === 200){
                    resolve.call(undefined,request.statusText)
                }else{
                    reject.call(undefined,request.statusText)
                }
            }
        }
    })
}

function success(e){
    console.log(e)
}

function fail(e){
    console.log(e)
}

myButton.addEventListener('click', ()=>{
    jQuery.ajax({
        url:'/xxx',
        method:'get'
    }).then(success,fail)
})