自己封装一个ajax

376 阅读1分钟

ajax

页面不刷新就可以和服务器进行交互

ajax原理

使用XMLHttpRequest对象发送http请求,然后接受服务器返回的数据

ajax交互流程

1 new一个XMLHttpRequest对象
2 打开连接
3 发送请求
4 接收数据

为什么要ajax

一个页面可能会有多个ajax请求,如果不封装一个ajax,那么每次都要写重复的代码。这样 代码冗余,不利于维护

使用get和post的区别

get 的参数拼接在url上,send()传递的是null
post send()传递的是请求参数,需要设置请求头
,

xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

代码

支持get,post;支持传递的参数是对象;模拟jqury封装的ajax

let $ = {
            params: function(obj) {
                let str = ''
                for (item in obj) {
                    //为啥不能用obj.item
                    str += item + '=' + obj[item] + '&'
                }
                //剪切多余的 &
                str = str.substr(0, str.length - 1)
                return str
            },
            ajax: function(options) {
                let xhr = new XMLHttpRequest()
                options.type.toLocaleLowerCase()
                //this的指向是$对象
                let data = this.params(options.value)
                if (options.type === 'get') {
                    options.url = options.url + '?' + data
                    data = null
                }
                //打开连接需要在设置请求头之前,否则报下面的错误
                //Uncaught DOMException: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.
                xhr.open(options.type, options.url)
                if (options.type === 'post') {
                    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
                }
                //相当于过滤器的作用
                if (options.beforesend && !options.beforesend()) {
                    return
                }
                xhr.send(data)
                xhr.onreadystatechange = function() {
                    if (xhr.readyState == 4) {
                        if (xhr.status == 200) {
                            console.log(xhr.responseText);
                            //如果success没有传递也不会报错
                            options.success && options.success(xhr.responseText)
                        } else {
                           //请求出错
                            options.error && options.error()
                        }
                        //请求完成
                        options.compelete && options.compelete()
                    }
                }
            }
        }
        $.ajax({
                url: 'http://localhost/14.php',
                type: 'get',
                data: {
                    value: '测试'
                },
                //下面的回调函数可以不传递
                beforesend: function() {
                    console.log('请求发送之前调用');
                    return true
                },
                success: function(res) {
                    console.log(res);
                },
                compelete: function() {
                    console.log('请求完成时调用');
                },
                error: function() {
                    console.log('请求出错时调用');
                }
            })