axios(二)XHR的理解和使用

本文详细介绍了XMLHttpRequest(XHR)的理解,包括它如何实现无刷新局部更新页面,区分普通HTTP与AJAX请求。同时,文章还探讨了XHR的API,如status、readyState、responseType等,并讲解了基于XHR的简单版axios实现,特点在于返回Promise并自动处理JSON响应。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ch2. XHR的理解和使用

2.1 理解

  1. 使用XMLHttpRequest(XHR)对象可以与服务器交互,也就是发送ajax请求
  2. 前端可以获取到数据,而无需让整个的页面刷新
  3. 这使得Web页面可以只更新页面的局部,而不影响用户的操作

2.2 区别一般http请求与ajax请求

  1. ajax请求是一种特别的http请求

  2. 对服务器来说,没有任何区别,区别在浏览器端

  3. 浏览器端发请求:只有XHR或fetch发出的才是ajax请求,其他所有的都是非ajax请求

  4. 浏览器端接收到响应

    (1)一般请求:浏览器一般会直接显示响应体数据,也就是我们常说的刷新/跳转页面

    (2)ajax请求:浏览器不会对界面进行任何更新操作,只是调用监视的回调函数并传入相关数据

2.3 API

  1. XMLHTTPRequest(): 创建XHR对象的构造函数

  2. status: 响应状态码值,比如200,400

  3. statusText: 响应状态文本

  4. readyState: 标识请求状态的只读属性

    0:初始

    1:open()之后

    2:send()之后

    3:请求中

    4:请求完成

  5. onreadystatechange: 绑定readyState改变的监听

  6. responseType: 指定响应数据类型,如果是json,得到响应后自动解析响应体数据

  7. response: 响应体数据,类型取决于responseType的指定

  8. timeout: 指定请求超时。默认为0没有限制

  9. ontimeout: 绑定超时的监听

  10. onerror: 绑定请求网络错误的监听

  11. open(): 初始化一个请求,参数为:{method, url, async}

  12. send(data): 发送请求

  13. abort(): 中断请求

  14. getResponseHeader(name): 获取指定名称的响应头值

  15. getAllResponseHeader(): 获取所有响应头组成的字符串

  16. setResponseHeader(name, value): 设置请求头

2.4 XHR的ajax封装(简单版axios)

2.4.1 特点

  1. 函数的返回值为promise,成功的结果为response,异常的结果为error

  2. 能处理多种类型的请求:GET/POST/PUT/DELETE

  3. 函数的参数为一个配置对象

    {

    ​ url: ’ ', //请求地址

    ​ method: ’ ', //请求方式为GET/POST/PUT/DELELTE

    ​ params: { }, //GET/DELETE请求的query参数

    ​ data: { }, //POST或DELETE请求的请求体参数

    }

  4. 响应json数据自动解析为js

2.4.2 实例

function axios({
    url,
    method = 'GET',
    params = {},
    data = {}
}){
    //返回一个promise对象
    return new Promise((resolve, reject) => {
        //处理method
        method = method.toUpperCase()
        //处理query参数(拼接到url)	id=1&xxx='abc'
        let queryString = ''
        Object.keys(params).forEach(key => {
            queryString += `${key}=${params[key]}&`
        })
        is(queryString){
            //去掉最后的&
            queryString = queryString.substring(0, queryString.length-1)
            //拼接到url上
            url += '?' + queryString
        }
        //1. 执行异步ajax请求
        //1.1 创建xhr对象
        const request = new XMLHttpRequest()
        //1.2 打开连接(初始化请求,没有请求)
        request.open(method, url, true)
        //1.3 发送连接
        if (mothod === 'GET' || method === 'DELETE') {
            request.send()
        }else if (method === 'POST' || method === 'PUT'){
            //1.3.1 告诉服务器请求体的格式是json
            request.setRequestHeader('Content-Type', 'application/json;charset=utf-8')
            request.send(JSON.stringify(data))	//1.3.2 发送json格式请求体参数
        }
        //2. 绑定状态改变的监听
        request.onreadystatechange = function(){
            //2.1 如果请求没有完成,直接结束
            if(request.readyState != 4){
                return
            }
            //如果响应状态码在[200, 299],代表成功
            const {status, statusText} = request
            //2.2 如果请求成功了,调用resolve()
        	if(status >= 200 &status <= 299){
                const response = {
                    data: JSON.parse(request.response)
                    status,
                    statusText
                }
                resolve(response)
            }else {	//2.2如果请求失败了,调用reject()
                reject(new Error('request error status is' + status))
            }
        }
    })
}
//1.GET请求:从服务器获取数据
function testGet(){
    axios({
        url: 'http://localhost:3000/posts',
        method: 'GET',
        params: {
            id: 1,
            xxx: 'abc'
        }
    }).then(
    	response => {
            console.log(response)
        },
        error => {
            alert(error.message)
        }
    )
}
//2.POST请求:服务器保存数据
function testPost(){
    axios({
        url: 'http://localhost:3000/posts',
        method: 'POST',
        data: {
			"title": "json-server---",
            "author": "typicode---"
        }
    }).then(
    	response => {
            console.log(response)
        },
        error => {
            alert(error.message)
        }
    )
}
//3.PUT请求:服务器更新数据
function testPut(){
    axios({
        url: 'http://localhost:3000/posts/1',
        method: 'PUT',
        data: {
			"title": "json-server+++",
            "author": "typicode+++"
        }
    }).then(
    	response => {
            console.log(response)
        },
        error => {
            alert(error.message)
        }
    )
}
//4.DELETE请求:服务器删除数据
function testDelete(){
    axios({
        url: 'http://localhost:3000/posts/2',
        method: 'DELETE'
    }).then(
    	response => {
            console.log(response)
        },
        error => {
            alert(error.message)
        }
    )
}
<think>嗯,用户想了解axiosAjax的区别以及它们各自的介绍。首先,我需要回忆这两个技术的背景用途。Ajax是一种用于创建异步Web应用的技术,而axios是一个基于Promise的HTTP客户端,通常用于浏览器Node.js环境。 接下来,我应该先分别介绍Ajaxaxios的基本概念。Ajax全称是Asynchronous JavaScript and XML,它允许网页在不重新加载的情况下与服务器交换数据。但Ajax本身并不是一个具体的API,而是一种技术方案,通常通过XMLHttpRequest对象来实现。不过,用户在使用原生Ajax时可能会觉得代码比较繁琐,需要处理兼容性回调地狱的问题。 然后是axios,它是一个第三方库,基于Promise封装,提供了更简洁的API更好的错误处理机制。相比原生Ajaxaxios支持拦截请求响应,自动转换JSON数据,并且可以在浏览器Node.js使用,这些特点让它在现代前端开发中更受欢迎。 用户可能需要知道它们之间的主要区别。比如,Ajax是技术统称,而axios是具体库;原生Ajax使用回调函数,axios使用Promise;axios有更多高级功能如拦截器、取消请求等。同时,也要提到fetch API,作为现代浏览器的原生方法,axios相比有什么优缺点,比如fetch需要手动处理JSON转换,而axios自动处理。 还需要考虑用户的实际应用场景。比如,在旧项目中使用jQuery的Ajax可能更常见,而在新项目中,axios或fetch更合适。另外,是否需要处理兼容性,或者需要更简洁的代码结构,这些因素都会影响选择。 另外,用户可能对如何选择使用哪个工具有疑问,所以需要给出一些建议。例如,如果项目已经使用jQuery,继续用它的Ajax可能更方便;如果是现代框架如React或Vueaxios更合适;如果不需要额外依赖,可以考虑fetch。 最后,要确保回答结构清晰,分点说明,帮助用户逐步理解两者的区别适用场景。同时,注意使用中文,避免技术术语过于晦涩,必要时举例说明。</think>### 一、基本概念分步解析 #### 1. Ajax 技术 (1)**技术本质** Ajax(Asynchronous JavaScript and XML)是一种**异步通信技术**,通过以下组合实现: - XMLHttpRequest(XHR)对象:核心通信接口 - JavaScript:控制请求发送与数据处理 - DOM:动态更新页面内容 (2)**原生实现示例** ```javascript var xhr = new XMLHttpRequest(); xhr.open('GET', '/api/data', true); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { console.log(JSON.parse(xhr.responseText)); } }; xhr.send(); ``` (3)**技术局限** - 回调地狱问题(多层嵌套回调) - 需手动处理响应数据格式(如JSON解析) - 浏览器兼容性处理(旧版IE需特殊处理) #### 2. Axios 库 (1)**核心特性** - 基于Promise的异步处理 - 自动JSON数据转换 - 请求/响应拦截器 - 客户端XSRF防护 - 请求取消功能(通过CancelToken) (2)**典型使用示例** ```javascript axios.get('/api/data') .then(response => { console.log(response.data); }) .catch(error => { console.error('Error:', error); }); ``` (3)**高级功能演示** ```javascript // 创建自定义实例 const api = axios.create({ baseURL: 'https://api.example.com', timeout: 5000 }); // 添加请求拦截器 api.interceptors.request.use(config => { config.headers.Authorization = `Bearer ${token}`; return config; }); // 添加响应拦截器 api.interceptors.response.use( response => response.data, error => Promise.reject(error) ); ``` ### 、技术对比表格 | 特性 | Ajax(原生XHR) | Axios | Fetch API | |---------------------|-----------------------|-------------------------|------------------------| | **语法复杂度** | 高(需手动封装) | 低(链式调用) | 中等(需次封装) | | **数据解析** | 手动处理 | 自动转换JSON | 需response.json() | | **错误处理** | 手动检测状态码 | 自动捕获HTTP错误 | 不拒绝HTTP错误状态 | | **取消请求** | 原生支持xhr.abort() | 通过CancelToken实现 | 通过AbortController | | **进度监控** | 支持上传/下载进度 | 支持 | 不支持 | | **浏览器兼容** | IE7+ | IE11+ | 现代浏览器 | ### 三、技术选型建议 #### 1. 推荐使用场景 - **传统项目维护**:jQuery的$.ajax仍是合理选择 - **现代SPA应用**:Vue/React+Axios是主流组合 - **轻量级需求**:Fetch API(需注意:`404`不会触发catch) - **需要文件上传进度**:Axios的onUploadProgress #### 2. 性能对比 - **包体积**:Axios(4kb gzip) vs Fetch(内置) - **执行效率**:原生XHR ≈ Fetch > Axios(差异可忽略) #### 3. 异常处理对比 ```javascript // Axios的错误捕获 axios.get('/api') .catch(error => { if (error.response) { // 服务器响应异常(4xx/5xx) } else if (error.request) { // 请求已发出但无响应 } else { // 配置错误 } }); // Fetch的错误处理 fetch('/api') .then(response => { if (!response.ok) throw new Error('HTTP error'); return response.json(); }) .catch(error => console.error(error)); ``` ### 四、演进趋势分析 1. **2015年前**:jQuery Ajax主导 2. **2015年**:Fetch API标准发布 3. **2016年**:Axios成为主流Promise方案 4. **2020年**:浏览器原生支持率突破92% 5. **2023年**:Axios仍保持每周2000万+下载量 ### 五、现代替代方案 1. **GraphQL客户端**:Apollo Client 2. **REST封装库**:SWR(React)、VueQuery 3. **全栈框架内置**:Next.js的API Routes 通过上述分层次的技术解析,开发者可以根据项目需求、团队技术栈、浏览器支持要求等因素,做出最适合的技术选型决策。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值