Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

探索AJAX #17

Open
Pomelo1213 opened this issue Feb 25, 2018 · 0 comments
Open

探索AJAX #17

Pomelo1213 opened this issue Feb 25, 2018 · 0 comments
Labels
JavaScript JavaScript

Comments

@Pomelo1213
Copy link
Owner

之前学习了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。

@Pomelo1213 Pomelo1213 added the JavaScript JavaScript label Aug 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JavaScript JavaScript
Projects
None yet
Development

No branches or pull requests

1 participant