Ajax+JSON学习一

Ajax+JSON学习一

文章目录

  • 前言
  • 一、Ajax简介
    • [1.1. Ajax基础](#1.1. Ajax基础)
    • [1.2. 同源策略](#1.2. 同源策略)
  • 二、Ajax的核心技术
    • [2.1. XMLHttpRequest 类](#2.1. XMLHttpRequest 类)
    • [2.2. open指定请求](#2.2. open指定请求)
    • [2.3. setRequestHeader 设置请求头](#2.3. setRequestHeader 设置请求头)
    • [2.4. send发送请求主体](#2.4. send发送请求主体)
    • [2.5. Ajax取得响应](#2.5. Ajax取得响应)
  • 总结

前言


一、Ajax简介

1.1. Ajax基础

Ajax 的全称是 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),是一种用于创建动态网页的技术。

Ajax 是一种使用现有标准的新方法,通过与服务器进行少量的数据交换,Ajax 可以使网页实现异步更新,这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

Ajax 可以提高系统性能,优化用户界面。很多框架以及代码库已将 Ajax 作为其必不可少的一个重要模块。

Ajax 工作原理:

在客户端和服务器之间加了一个中间层:Ajax 引擎。由 Ajax 引擎独立向服务器请求数据,前端获取到 Ajax 返回的数据后,可以使用新数据来更新页面、或进行其它操作,使用户请求和服务器响应异步化 ,从而保证了在不刷新页面的前提下可以局部更新网页内容。

Ajax 使用示例

合理的利用 Ajax 技术,可以创建出交互丰富的动态式网页,让用户操作起来更加流畅,较为典型的应用有:

  1. 按需获取数据,最大限度地减少冗余请求及响应对服务器造成的负担;
  2. 实时验证表单的某条数据,无需等到提交整个表单时再验证;
  3. 页面无刷新更新,更好的响应用户;
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Tryrun 1</title>
</head>
<body>
    <div id="view">
        <p>点击下面的按钮,将 Ajax 请求回来的数据更新在该文本内</p>
    </div>
    <button type="button" id="btn">发起 Ajax 请求</button>

    <script>
        document.getElementById("btn").onclick = ajaxRequest;

        function ajaxRequest () {
            var xhr = new XMLHttpRequest();

            xhr.open("GET", "https://www.w3cschool.cn/statics/demosource/ajax_info.txt", true);
            xhr.send();

            xhr.onreadystatechange = function(){
                if (xhr.readyState === 4 && xhr.status === 200) {
                    document.getElementById("view").innerHTML = xhr.responseText;
                }                
            }
        }
    </script>
</body>

Ajax 的优缺点

Ajax 的优点:

最大的优点是页面无刷新更新,用户的体验非常好;

使用异步方式与服务器通信,具有更迅速的响应能力;

可以将一些服务器工作转移到客户端,利用客户端资源来处理,减轻服务器和带宽的压力,节约空间和带宽租用成本;

技术标准化,并被浏览器广泛支持,不需要下载插件或者小程序;

Ajax 可使因特网应用程序更小、更快、更友好。

Ajax 的缺点:

Ajax 不支持浏览器 back 返回按钮;

有安全问题,Ajax 暴露了与服务器交互的细节;

对搜索引擎不友好;

破坏了程序的异常机制;

不容易调试。

1.2. 同源策略

一个 URL 地址可以有以下几个组成部分:scheme: //host:post/path?query#fragment

scheme:通信协议,一般为 http 、https;

host:域名;

post:端口号,此项为可选项,http 协议默认的端口号为 80,https 协议默认的端口号为 443;

path:路径,由 "/ "隔开的字符串;

query:查询参数,此项为可选项;

fragment:信息片段,用于指定网络资源中的某片断,此项为可选项;

什么是同源策略?

同源策略是一种安全协议,是客户端脚本(尤其是 JavaScript)中重要的安全度量标准,指一段脚本只能读取同一来源的窗口和文档的属性。

划重点:何为同源?同源指的是 URL 地址中的 协议、域名、端口 三者 都 相同。

为什么要有同源策略?

我们在使用 Ajax 请求后端数据时,只能跟同源的后端接口进行数据交互,即:后端接口的 URL 与发起 Ajax 请求的页面 URL 之间,需要满足同源策略。

为了数据的安全性。若没有同源策略的限制,那么黑客就可以在他的页面上任意请求你的后端数据,造成数据库内容被盗取、隐私数据泄漏。

实现跨域请求的方式

虽然 Ajax 请求需要满足同源策略,然而在一些场景中,你真的需要 Ajax 访问其它 "源" 的数据(称为跨域访问),这时需要后端服务器进行相应的设置。

复制代码
如果服务器端支持 CORS,可以通过设置Access-Control-Allow-Origin来实现跨域。如果浏览器检测到相应的设置,就会允许 Ajax 进行跨域访问。

扩展:解决跨域问题的其它方式

JSONP 技术;

在服务端设置代理模块;

通过修改 window.name 实现跨域;

使用 HTML5 中新引进的 window.postMessage 方法来跨域传送数据;

等...

二、Ajax的核心技术

2.1. XMLHttpRequest 类

Ajax 技术的核心是XMLHttpRequest类,简称 XHR,它允许脚本异步调用 HTTP API

浏览器在XMLHttpRequest类上定义了 HTTP API,这个类的每个实例都表示一个 独立 的 请求/响应 对象,并且这个实例对象上的属性和方法允许 指定细节 和 提取响应数据。

javascript 复制代码
//  变量xhr来表示这个实例
var xhr = new XMLHttpRequest();

2.2. open指定请求

创建 XMLHttpRequest 对象之后,发起 HTTP 请求的下一步是调用 XMLHttpRequest 对象的open方法,指定 HTTP 请求的两个必需部分:请求方法 和 URL

javascript 复制代码
var xhr = new XMLHttpRequest();
// 其中请求方法为大写
xhr.open("GET", "/statics/demosource/demo_get_json.php");

允许脚本以异步的方式发起 Ajax 请求,是XMLHttpRequest技术的一个重要特性,可避免发生因网速慢等原因导致脚本代码阻塞、页面卡死现象;

2.3. setRequestHeader 设置请求头

如果你的 HTTP 请求需要设置请求头,那么调用 open 方法之后的下个步骤就是设置它,使用的方法是:setRequestHeader

示例:POST 请求设置 "Content-Type" 头来指定请求主体的编码格式

javascript 复制代码
//语法
xhr.setRequestHeader(name, value)

//示例:
var xhr = new XMLHttpRequest();
xhr.open("POST", "/statics/demosource/demo_post_json.php");
// 在 open 方法之后设置请求头
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

说明:

不能自己指定 "Content-Length"、"Date"、"Referer" 或 "User-Agent" 头,XMLHttpRequest将自动添加这些头而防止伪造它们。类似地,XMLHttpRequest对象还会自动处理 cookie、链接时间、字符集和编码判断,所以你无法使用setRequestHeader方法设置它们。

2.4. send发送请求主体

使用 XMLHttpRequest 发起 HTTP 请求的最后一步是指定可选的请求主体、并向服务器发送它,使用的方法是:send

示例1:GET 请求

javascript 复制代码
var xhr = new XMLHttpRequest();
xhr.open("GET", "/statics/demosource/demo_get_json.php");

// 无请求主体
xhr.send(null);

GET 请求,用于从服务器获取资源。它通常不需要传递请求主体,因为它的参数通常都包含在 URL 中。因此,在使用 XMLHttpRequest 对象发送 GET 请求时,可以省略或传递 null 作为请求主体

示例2:POST 请求

javascript 复制代码
var xhr = new XMLHttpRequest();
xhr.open("POST", "/statics/demosource/demo_post_json.php");

// 把 msg 作为请求主体发送
xhr.send(msg);

POST 请求通常用于向服务器提交数据,因此它通常需要具有请求主体,可在 send 方法中指定它;

POST 请求的请求主体,应该匹配setRequestHeader方法所指定的 "Content-Type" 头。

2.5. Ajax取得响应

一个完整的 HTTP 响应由 状态码、响应头和 响应主体 组成,这三者都可以通过XMLHttpRequest对象提供的属性和方法获取。

为了能够在 HTTP 响应准备就绪时得到通知,必须监听XMLHttpRequest对象上的readystatechange事件。但为了理解这个事件类型,需要先了解下readyState属性,因为该事件监听的是readyState属性值的改变。

示例:XMLHttpRequest对象上的readyState属性在 HTTP 请求过程中,会从 0 变到 4

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button id="btn">点我观察 readyState 属性的改变</button>

    <script>
        var oBtn = document.getElementById("btn");

        oBtn.onclick = function () {
            var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");

            alert(xhr.readyState);
            xhr.onreadystatechange = function () {
                alert(xhr.readyState);
            }

            xhr.open("GET", "/statics/demosource/demo_get_json.php");
            xhr.send();
        }
    </script>
</body>
</html>

readyState属性是一个整数,它的值代表了不同的 HTTP 请求状态。

readyState属性值的含义:

0:初始值,表示请求未初始化,open方法尚未调用;

1:启动请求,open 方法已经调用,但尚未调用 send 方法;

2:请求发送,已经调用 send 方法,但尚未接收到响应;

3:接收响应,已经接受到部分响应数据,主要是响应头;

4:HTTP 响应完成,已经接收到全部响应数据,而且可以在客户端使用。

即每次readyState属性值的改变都会触发readystatechange事件,但只有readyState属性值为 4 时才是我们所关心的状态,因为只有这个状态才表示 HTTP 的响应准备就绪,可以真正意义上的结合服务器所响应的数据来实现我们的业务需求。

因此,我们 Ajax 请求的代码通常都是这样的:

javascript 复制代码
var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) {
       oTip.innerText = "HTTP 响应完成";
    }
};

xhr.open("GET", "/statics/demosource/demo_get_json.php");
xhr.send();

"响应完成" 只代表 HTTP 请求结束,至于服务器的响应状态:是请求成功还是请求错误,又或者是服务器错误,需要通过 HTTP 状态码判断,它存储在XMLhttpRequest的status属性上;

status属性会以数字的形式保存服务器响应的 HTTP 状态码,

诸如使用最频繁的 "200" 表示请求成功,"404" 表示 URL 不能匹配服务器上的任何资源。

HTTP 状态码是用来表示网页服务器响应状态的 3 位数字代码,所有状态码的第一个数字代表了响应的五种状态之一:

1xx:临时响应

2xx:成功

3xx:重定向

4xx:请求错误

5xx:服务器错误

示例:Ajax 请求成功

javascript 复制代码
var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {
    if (xhr.readyState !== 4) return;
    if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
                    oTip.innerText = "HTTP 请求成功";
                }
};

xhr.open("GET", "/statics/demosource/demo_get_json.php");
xhr.send();

responseText属性以字符串的形式存储了响应主体,即:服务器的响应数据。

例如:响应 JSON 数据

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>sss</title>
</head>
<body>
    <div>页面更新于:<span id="time"></span></div>
    <br>
    <button id="btn">点我发起 Ajax 请求</button>
    
    <script>
        var oBtn = document.getElementById("btn"),
            oTime = document.getElementById("time");

        oBtn.onclick = function () {
            var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");

            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) return;
                if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
                    var res = JSON.parse(xhr.responseText);
                    oTime.innerText = res.date;
                }
            };

            xhr.open("GET", "/statics/demosource/demo_get_json.php");
            xhr.send();
        }
    </script>
</body>
</html>

查询 HTTP 响应头的方法

在XMLHttpRequest对象上,可通过getAllResponseHeaders和getResponseHeader方法查询响应头信息。

  1. getAllResponseHeaders方法无参数,用于一次性返回可查询的全部响应头信息

  2. getResponseHeader方法用于查询单一响应头信息,需要传入一个指定 "头名称" 的字符串作为参数:getResponseHeader(headerName)

javascript 复制代码
var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {
    if (xhr.readyState !== 4) return;
    if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
        // 查询 "Content-Type" 响应头信息
        alert( xhr.getResponseHeader("Content-Type") );
    }
};

xhr.open("GET", "/statics/demosource/demo_get_json.php");
xhr.send();

Ajax 的同步响应

如果将false作为第三个参数传递给open方法,那么调用send方法将 阻塞 后续脚本的执行 直到 HTTP 请求完成。在这种情况下,不再需要监听readystatechange事件,因为send方法后面的代码一定会等到 HTTP 请求完成后再执行。

javascript 复制代码
var xhr = new XMLHttpRequest();

// 指定 open 方法的第三个参数为 false
xhr.open("GET", "/statics/demosource/demo_get_json.php", false);

// send 方法的调用将阻塞后面代码的执行,直到此次 HTTP 请求完成
xhr.send();

// 不再需要监听 readystatechange 事件
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
    oTime.innerText = JSON.parse(xhr.response).date;
} else {
    // 如果请求不成功,就报错
    throw new Error(xhr.status);
}

若 HTTP 请求的时间超出预期,可以调用XMLHttpRequest对象上的abort方法来中止 HTTP 请求。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="tip">页面更新于:<span id="time"></span></div>
    <br>
    <button id="btn">点我发起 Ajax 请求</button>
    <hr>
    <p>提示:为了更加确保能演示出请求被中止,示例中将定时器设置成 0 毫秒</p>

    <script>
        var oBtn = document.getElementById("btn"),
            oTime = document.getElementById("time"),
            oTip = document.getElementById("tip");

        oBtn.onclick = function () {
            var xhr = window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
            var timer = null;

            xhr.onreadystatechange = function () {
                if (xhr.readyState !== 4) return;
                if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
                    clearTimeout(timer);
                    var res = JSON.parse(xhr.responseText);
                    oTime.innerText = res.date;
                }
            };

            xhr.open("GET", "/statics/demosource/demo_get_json.php");
            xhr.send();

            timer = setTimeout(function(){
                xhr.abort();
                alert("请求被中止");
                oTip.innerText = "页面加载超时";
            }, 0)
        }
    </script>
</body>
</html>

总结

--2023--12--15

相关推荐
西岸行者6 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意6 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码6 天前
嵌入式学习路线
学习
毛小茛6 天前
计算机系统概论——校验码
学习
babe小鑫6 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms6 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下6 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。6 天前
2026.2.25监控学习
学习
im_AMBER6 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J6 天前
从“Hello World“ 开始 C++
c语言·c++·学习