前端技术-AJAX

AJAX

介绍

AJAX是一种网页开发技术,它的全称是“异步JavaScript和XML”。简单来说,AJAX允许网页在不重新加载整个页面的情况下,与服务器交换数据和更新部分网页内容。

我们可以用“餐馆点餐”来比喻AJAX技术:想象一下,你正在餐馆吃饭,此时你想再加一份菜,但你不想离开座位重新点餐,这时候服务员(就像AJAX技术)可以帮你把你的菜单传给厨房(服务器),然后厨房做好菜后,服务员再把菜端给你,而不需要你离开座位重新排队点餐。这样,你的用餐体验变得更加顺畅,而不需要中断。

AJAX实例

以下我们创建了一个ajax实例供参考:

<!DOCTYPE html>
<html>
    <head>
        <title>
            你好,AJAX!
        </title>
    </head>
    <body>
        <h1 id="myh1">点击以下按钮修改内容</h1>
        <button onclick="run()">RUN</button>
    </body>
    <script>
        function run(){
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange= ()=>{
                if(xhr.readyState==4 && xhr.status==200){
                    console.log('请求已完成且响应已就绪');
                    var myh1 = document.getElementById("myh1");
                    myh1.textContent = xhr.responseText;
                }
            }
            xhr.addEventListener('readystatechange',()=>{
                console.log('readyState属性改变了');
            });
            xhr.open('GET','<url>',true); //url是指你请求资源的目标地址
            xhr.send();
        }
    </script>
</html>

AJAX技术是用XHR对象或Fetch API进行网络请求后获取到数据再通过操作DOM进行页面更新来实现的。


创建一个XHR对象

介绍

AJAX技术包含“网络请求”和“页面更新”两部分,其中使用XHR(即XMLHttpRequest)对象进行网络请求则是“网络请求”部分的核心。

XHR对象,全称是XMLHttpRequest对象,是JavaScript的一个内置对象,它允许网页通过JavaScript向服务器发送请求和从服务器接收数据,而不需要重新加载整个页面。这使得网页可以实现异步数据交换,是AJAX技术的核心。

语法

IE7以上(包括IE7、Firefox、Chrome、Safari 以及 Opera)的新版本浏览器创建XHR对象是使用XMLHttpRequest构造函数进行创建:

var xhr = new XMLHttpRequest();

IE7以下的老版本浏览器则是使用ActiveXObeject构造函数创建ActiveX对象,其中传入的参数为"Microsoft.XMLHTTP":

var ax = new ActiveXObeject("Microsoft.XMLHTTP");

“Microsoft.XMLHTTP”:这是传递给ActiveXObeject构造函数的参数,它指定了要创建的ActiveX控件的ProgID(程序标识符)。ProgID是用于标识COM对象(在Windows操作系统中使用的组件对象模型)的一个字符串。


使用XHR网络请求

XHR请求

在我们创建好了一个XHR对象之后,就需要使用这个对象来进行网络请求的实现了。在XHR对象中,我们使用open()方法和send()方法来实现对网络资源或本地资源进行获取,以下是这两个方法的具体信息和使用。

open()

XHR.open()方法是用来初始化一个新的请求,或重新初始化一个请求。

xhr.open("method","url","async");
参数类型描述
methodString填写请求的方法,如GET(获取)、POST(提交)、PUT(增加)、DELETE(删除)。
urlString填写请求资源的目标地址
asyncBoolean是否为异步执行操作?true为是,false为否

“异步执行操作”就是当请求发送之后,当请求目标还未响应请求的时候,继续往下执行后面的代码;相反,“同步”就是指等待请求目标响应请求之后再往下执行后面的代码。但在XHR网络请求中,更加推荐使用“异步”,因为“同步”会导致JavaScript主线程被阻塞,导致其他代码不会执行。

send()

XHR.send()方法用于发送 HTTP 请求。

xhr.send("post_content");
参数类型描述
post_contentString用于POST发送内容,若是GET则不填。

如果是异步请求(默认为异步请求),则此方法会在请求发送后立即返回;如果是同步请求,则此方法直到响应到达后才会返回。

XHR响应

在XHR对象中一般通过读取responseText和responseXML属性来获取请求目标返回来的响应数据,除此之外还有一些不常用的属性:

属性描述
responseText获得字符串形式的响应数据。
responseXML获得XML/HTML形式的响应数据。
responseType获得响应数据中包含的数据类型。
response

返回响应的正文。返回的类型为 ArrayBufferBlobDocument、JavaScript Object 或字符串中的一个。

responseURL获得响应的序列化URL

responseText获取响应数据:

document.getElementById("myDiv").innerText = xhr.responseText;

responseXML获取响应数据:

console.log(xhr.responseXML);

XHR网络请求的状态

XHR.readyState

介绍

当请求被发送给服务器时,该XHR对象会处在各个不同的阶段,而XHR对象中的readyState属性便是用来描述XHR对象所处阶段的。

它包含以下四个状态值以及对应的状态信息:

状态状态描述
0UNSENT已创建XHR对象,但并未调用open()方法。
1OPEN

open()方法已被调用。在这个状态中,可以通过 setRequestHeader() 方法来设置请求的头部。

2HEADERS_RECEIVED

send()方法已被调用,并且头部和状态已经可获得。

3LOADING

请求处理中,并且responseText属性已包含部分数据。

4DONE

请求已完成且响应已就绪。

一般在使用XHR.readyState时会搭配着XHR.status(HTTP状态码)一起使用,如下示例:

var xhr = new XMLHttpRequest(); //创建并初始化xhr对象
if (xhr.readyState==4 && xhr.status==200){
        //在“请求操作完成”且“请求成功”的状态下执行的逻辑代码
}

常见的HTTP状态码

状态码状态描述
200请求成功。
301资源(网页等)被永久转移到其它URL。
404请求的资源(网页等)不存在。
500服务器内部错误,无法完成请求。

XHR.readyState与HTTP状态码的区别

XHR.readyState指的的是XMLHttpRequest对象的当前状态。它是一个只读属性,用xhr.readyState来读取。

HTTP状态码指的是在使用HTTP协议请求服务器完成后,由服务器发送,并作为响应的一部分的一种代码,它表明了当前请求的结果。它同样也是一个只读属性,用xhr.status来读取。

Tip:XMLHttpRequest网络请求同样也是基于HTTP协议的网络请求。

XHR.onreadystatechange

介绍

只要各种对象(如WebSocket,XMLHttpRequest)的readyState属性发生变化时,就会调用相应的处理函数。XHR.onreadystatechange方法就是会在XHR.readyState属性发生变化的时候被调用。

语法

使用XMLHttpRequest对象中的事件处理方法onreadystatechange,对其赋值一个函数来执行发生该事件之后的逻辑代码:

xhr.onreadystatechange = function(){
     //当readyState属性改变时的逻辑代码
}

注册一个事件监听器来监听readystatechange事件,再执行事件发生后的回调函数:

xhr.addEventListener('readystatechange',()=>{
      //当readyState属性改变时的逻辑代码
});

使用Fetch API网络请求

介绍

Fetch API 是一个现代的网络请求工具,它提供了一种更简单、更强大的方式来发起网络请求。可以直接使用JavaScript异步地请求资源,而非使用传统的XHR对象来进行网络请求。以下是一些Fetch API的基本特点:

  1. 基于Promisefetch返回一个Promise对象,这意味着可以使用.then()方法来处理响应,也可以使用async/await语法。

  2. 灵活的参数fetch接受一个URL作为必须的参数,并且可以接受一个可选的配置对象,用于自定义请求的各个方面,如方法、头信息、身体数据等。

  3. 模块化fetch的Response和Request对象是模块化的,可以单独使用,便于更细粒度的控制。

  4. 跨域请求:默认情况下,fetch遵循同源策略,但可以通过CORS(跨源资源共享)来支持跨域请求。

  5. 不需要额外的库fetch是原生支持的,不需要引入像jQuery这样的库。

语法

发起请求

fetch(url,options).then((response)=>{
     //处理响应
}).catch((error)=>{
     //处理错误
});

配置选项

const options = {
  method: 'GET', // 或 'POST', 'PUT', 'DELETE', 等
  headers: {
    'Content-Type': 'application/json'
    // 其他头部信息
  },
  body: JSON.stringify(data) // 如果是POST或PUT请求,可以包含一个请求体
};

处理响应

  • response.ok:布尔值,表示请求是否成功。
  • response.status:HTTP状态码。
  • response.statusText:状态文本。
  • response.headers:响应头信息。
  • response.json():将响应体解析为JSON。
  • response.text():将响应体解析为文本。

示例

fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok ' + response.statusText);
    }
    return response.json();
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    console.error('There has been a problem with your fetch operation: ', error);
  });

Tip:fetch不会自动将HTTP错误状态(如404或500)视为拒绝,即使响应的ok属性为false,它也会解析为一个成功的Promise。因此,需要手动检查response.okresponse.status来决定是否抛出错误。

XHR和Fetch API的区别

语法:XHR使用传统的回调函数,而Fetch API基于Promise,语法更现代、简洁。
错误处理:XHR需要检查状态码和监听错误事件,Fetch API通过Promise的拒绝来处理网络错误。
默认行为:XHR默认发送cookie,Fetch API默认不发送。
进度事件:XHR提供进度事件,Fetch API需要额外处理。
兼容性:XHR在所有浏览器中都支持,Fetch API在较新浏览器中支持较好。
使用场景:XHR适用于需要兼容旧浏览器的项目,Fetch API适用于现代Web应用。


可能出现的问题

跨源资源共享(CORS)政策问题

运行代码的时候,可能会在浏览器控制台中出现以下错误提示:

<your-filename>:1  Access to XMLHttpRequest at '<your-url>' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

问题分析

该错误是由于浏览器跨源资源共享政策导致的,当你从源(本地文件或者不同域的网页)尝试通过XMLHttpRequest方法请求另一源的资源时,由于没有正确设置响应头:Access-Control-Allow-Origin 从而使得浏览器会阻止这个请求。

解决方案

如果使用的是Node.js和Express的服务器应用,可以在代码中添加如下代码:

app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值