今天看啥  ›  专栏  ›  Pomelo1213

探索AJAX

Pomelo1213  · 掘金  ·  · 2018-02-27 02:31

之前学习了JSONP可以发送请求去获取数据,JSONP传送门然后通过callback来异步的执行我们预先准备好的函数。

可是JSONP只能发送get请求,这是不是太单一了?需求很多的变化,对于复杂一点的需求的话,无法满足,所以我们来试试用AJAX来实现跨域。

开工


先实现一个点击按钮发送一个请求,这里就需要介绍了一个WEB的API:XMLHttpRequest,MDN解释:它为客户端提供了在客户端和服务器之间传输数据的功能。提供一个通过URL来获取数据的简单方式,并且不会使整个页面刷新。

下面就用这个只是做一个简单的实现:点击一个按钮,发送一个请求:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <button id="button">点我</button>
<script>
    button.addEventListener('click', () => {
        let request = new XMLHttpRequest()
        request.open('get', '/xxx',)  //使用open带入url和一个请求
        request.setRequestHeader('Pomelo', '18')
        request.send()  //发送请求
        request.onreadystatechange = () => {
            if(request.readyState === 4){
                if(request.status >= 200 && request.status < 300){
                    let string = request.responseText
                    let obj = window.JSON.parse(string)
                    console.log(request.getAllRequestHeaders)
                    console.log(obj)
                }else if(request.status >= 400){
                    console.log('请求失败')
                }
            }
        }
    })
</script>
</body>
</html> 

readystate

这样就可以实现一个异步的get请求。onreadystatechage监听readystate的变化,用一个函数来处理这个变化。 这里需要列举一下readystate的数值及其含义。

readystate 状态 描述
0 UNSENT(未打开) open()方法还未被调用
1 OPENED(未发送) open()方法已经被调用
2 HEADERS_RECEIVED(已获取响应头) send()方法已经被调用,响应头和响应状态已经返回
3 LOADING(正在下载响应体) 响应体下载中;responseText中已经获取了部分数据
4 DONE(请求完成) 整个请求过程已经完毕

目前来这个实现还不错,但是每次调用就需要创建一个按钮去发请求。发请求。发请求。这样不会很麻烦吗?我们模仿JQuery那样试试看:

 window.jquery.ajax = function(options){
        let url = options.url
        let method = options.method
        let body = options.body
        let header = options.header
        let success = options.successFn
        let fail = options.failFn
        let request = new XMLHttpRequest()
        request.open(method, url) //在get请求下chrome 默认不显示request的第四部分  
        for(let key in header){
            let value = header[key]
            request.setRequestHeader(key, value)
        }
        request.send(body)
         request.onreadystatechange = () => {
             if(request.readyState === 4){
                if(request.status >= 200 && request.status < 300){                
                     let string = request.responseText
                    success.call(undefined, string)
                 }else if(request.status >= 400){
                    fail.call(undefined, request)
                 }
             }
         }
    }

这样一做,咱们就可以使用这样的形式调用:

jquery.ajax({
    url: '/xxx',
    method: 'get',
    body: 'hello',
    header: 'Pomelo',
    success: successFn,
    fail: failFn
})

使用ES6特性来优化


这样还不错,如果加上我们ES6的新特性,实现会更加优美:

 window.jquery.ajax = function({url, method, body, header}){ //ES6 解构赋值
        return new Promise(function(resolve, reject){ //Promise的特性,不用带入success和fail函数。
            let request = new XMLHttpRequest()
            request.open(method, url) //在get请求下chrome 默认不显示request的第四部分 
            for(let key in header){
                let value = header[key]
                request.setRequestHeader('ni', 'hao')
            }
            request.onreadystatechange = () => {
                if(request.readyState === 4){
                    if(request.status >= 200 && request.status < 300){
                        let string = request.responseText
                        resolve.call(undefined, string)
                    }else if(request.status >= 400){
                        reject.call(undefined, request)
                    }
                }
            }
            request.send(body)  
        })
    }

这样就完成了优美的ajax的实现。调用如下:

 jquery.ajax({
         url: '/xxx',
         method: 'post',
         body: 'hello everyone',
         header: {
             'Pomelo': '18',
             'Hello': '18'
         }
       }
   }).then(
       (xx) => { console.log(xx) },
       (xx) => { console.log(xx) }
    )

这样是不是就好看许多,简单的就实现了一个ajax。




原文地址:访问原文地址
快照地址: 访问文章快照