关于原生ajax请求及其封装

1. 关于get和post请求的区别

基础的区别就是get请求时将参数拼接在地址栏后面,比如我们在百度搜索你好的时候,跳转的地址为

https://www.baidu.com/s?ie=UTF-8&wd=你好

get方法是将我们请求的关键字和值用=连接做成一个字符串,多个键值对用&连接,最后用?分隔连在地址后面;因此我们也能显而易见的看出get方法速度快,但是不太安全以及长度限制等劣势,如果时前台传递用户名和密码的时候,直接拼接在地址栏就不可以了,地址栏的长度也有限制,所以不能无限制的添加参数。

而post请求则与之相反,不会拼接在地址栏中,而是随着协议传递,因此保证了安全性并扩大了数据长度;同时速度可能会相较于get慢一些,但实际使用中并感觉不到很大的区别,因此不必过分纠结。

在实际应用中,我们使用post和get只要是因为请求的原因不同,GET一般用于获取/查询资源信息,而POST一般用于更新资源信息;而且get请求时幂等的,什么是幂等呢?幂等的意味着对同一URL的多个请求应该返回同样的结果。

幂等(idempotent、idempotence)是一个数学或计算机学概念,常见于抽象代数中。   
幂等有一下几种定义:   
+对于单目运算,如果一个运算对于在范围内的所有的一个数多次进行该运算所得的结果和进行一次该运算所得的结果是一样的,那么我们就称该运算是幂等的。比如绝对值运算就是一个例子,在实数集中,有abs(a)=abs(abs(a))。   
+对于双目运算,则要求当参与运算的两个值是等值的情况下,如果满足运算结果与参与运算的两个值相等,则称该运算幂等,如求两个数的最大值的函数,有在在实数集中幂等,即max(x,x) = x。

2. XMLHttpRequest.readyState

XHR.readyState 的取值为(0,1,2,3,4),而且状态也是不可逆的:

  • 0:请求未初始化,还没有调用 open()。

  • 1:请求已经建立,但是还没有发送,还没有调用 send()。

  • 2:请求已发送,正在处理中(通常现在可以从响应中获取内容头)。

  • 3:请求在处理中;通常响应中已有部分数据可用了,没有全部完成。

  • 4:响应已完成;您可以获取并使用服务器的响应了。

在编码原生ajax的时候,我们开始处理响应的时候就是当readyState等于4的时候。

3. XMLHttpRequest.status

当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含 HTTP 状态码的信息头(server header)用以响应浏览器的请求。

HTTP 状态码的英文为 HTTP Status Code。。

下面是常见的 HTTP 状态码:

  • 200 - 请求成功

  • 301 - 资源(网页等)被永久转移到其它URL

  • 404 - 请求的资源(网页等)不存在

  • 500 - 内部服务器错误

HTTP 状态码分类

HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型。响应分为五类:信息响应(100–199),成功响应(200–299),重定向(300–399),客户端错误(400–499)和服务器错误 (500–599):

分类 分类描述
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

更多请参考:HTTP 状态码

4. Content-Type

上述讲过我们使用get请求,关于请求的数据,我们是将请求的关键字和值用=连接做成一个字符串,多个键值对用&连接,最后用?分隔连在地址后面,为了能够让浏览器理解我们如这样传参的,我们要设置请求头里的Content-Type属性,将其设置为application/x-www-form-urlencoded;这样浏览器就能解读我们拼接的字符串,找到我们要搜索的数据了。

5. XMLHttpRequest.open( )

XMLHttpRequest.open(method, url, async):为初始化一个请求,在我们建立了XMLHTTRequest后,用这个方法去定义我们的访问方式(method)比如get和post,给出访问地址(url);async是一个布尔值,表示是否异步执行操作,默认为true。如果值为false;如果true,则为异步执行,已完成事务的通知可供事件监听器(XMLHttpRequest.onreadystatechange)使用;false表示同步进行,会阻塞后面的程序执行,同步 AJAX 请求会造成浏览器失去响应,许多浏览器已经禁止在主线程使用。

6. 原生js封装ajax(使用promise)

/*
      @param {url,data,dataType,success,error}  以对象形式传参

      url   请求地址  不能为空
      data  参数  {username:'zs',pwd:123}
      dataType  返回结果是否以json解析 默认json
      success   成功的回调函数
      error     失败回调函数
    */

class axios {
    static get(params = {}) {
        return axios.http('get', params)
    }
    
    static post(params = {}) {
        return axios.http('post', params)
    }

    static http(method, params) {
        //1 解析参数
        let { url, data, dataType = 'json', success, error } = params;

        // 2 url 不能为空
        if (!url) {
            throw new Error('url不能为空..');
        }
        // 3 参数的构造
        let param = null;
        if (data) {
            param = [];
            for (let attr in data) {
                param.push(`${attr}=${data[attr]}`)
            }
            // 以 &分割为字符串
            param = param.join('&');
            // 判断是get请求,则将参数拼接到url后面
            if (method == 'get') {
                url = url + '?' + param;
                param = null;
            }
        }

        return new Promise((resolve, reject) => {
            // 创建核心对象
            const xhr = new XMLHttpRequest()
            // 打开,建立连接
            xhr.open(method, url, true)
            // 设置数据头
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
            // 发送请求
            xhr.send(param)
            // 处理响应
            xhr.onreadystatechange = function () {
                // 请求处理完毕,响应就绪
                if (xhr.readyState === 4) {
                    // HTTP 状态码 2xx 表示成功
                    if (xhr.status >= 200 && xhr.status < 300) {
                        // 获取响应数据
                        let data = xhr.response
                        // 如果预期从后端返回的是 JSON 格式的数据,则需要进行 JSON 解析转换
                        if (dataType === 'json') {
                            data = JSON.parse(data)
                        }
                        // 后续数据处理逻辑
                        // success && success(data)
                        resolve(data)
                    } else {
                        // 有错误,则传递HTTP状态码
                        // error && error(xhr.status)
                        reject(xhr.status)
                    }
                }
            }
        })
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容