Ajax 简明教程
What is AJAX?
AJAX 是异步 JavaScript 和 XML 的缩写。AJAX 并不是一种编程语言或技术,而是一种包括 HTML、XHTML、CSS、JavaScript、DOM、XML、XSLT 和 XMLHttpRequest 对象在内的多种 Web 相关技术的组合。AJAX 模型允许 Web 开发人员创建能够与用户动态交互的 Web 应用程序。它还能够快速向 Web 服务器发出后台调用以检索所需的应用程序数据,然后更新网页中的小部分,而无需刷新整个网页。
与传统的 Web 应用程序相比,AJAX 应用程序的速度和响应速度要快得多。它通过允许它们在用户在前台工作时在后台进行通信,从而在客户端和服务器之间创造了极大的平衡。
在 AJAX 应用程序中,Web 浏览器和服务器之间的数据交换是异步的,这意味着 AJAX 应用程序在不暂停应用程序执行的情况下提交对 Web 服务器的请求,并且还可以在返回请求的数据时对其进行处理。例如,Facebook 使用 AJAX 模型,因此每当我们喜欢任何帖子时,点赞按钮的计数就会增加,而不是刷新整个页面。
Working of AJAX
传统的 Web 应用程序是通过以预定义的顺序通过链接添加松散的网页创建的。用户可以通过这些链接从一个页面移动到另一个页面,以与应用程序的不同部分进行交互。此外,HTTP 请求用于向 Web 服务器提交用户操作的响应。接收到请求后,Web 服务器通过返回一个新网页来满足请求,然后该网页显示在 Web 浏览器中。此过程包括大量页面的刷新和等待。
通用网络加快了网页应用程序的工作速度。通过在网页上传递数据或允许数据在现有的网页应用程序内显示,通用网络提供了类似桌面的感受。它将松散集成的网页替换为紧密集成的网页。通用网络应用程序非常高效地利用资源。它在网页应用程序和网络服务器之间创建了一个名为通用网络引擎的附加层,由于这个附加层,我们能够使用 JavaScript 发起后台服务器调用,并检索所需数据,能够在不完全重新加载网页的情况下更新网页的请求部分。它减少了页面刷新时间并为用户提供了快速响应的体验。异步进程通过与客户端计算机分工,降低了网络服务器的工作量。由于工作量减少,网络服务器变得更加响应且更快速。
AJAX Technologies
通用网络使用的技术已经在现代浏览器中实现。因此,客户端不需要额外的模块来运行通用网络应用程序。通用网络使用以下技术:
-
{s0} − 它是 AJAX 的重要部分。它允许你创建客户端功能。或者我们可以说它用于创建 AJAX 应用程序。
-
{s1} − 它用于在 Web 服务器和客户端之间交换数据。
-
{s2} − 它用于在 Web 浏览器和 Web 服务器之间执行异步数据交换。
-
{s3} − 它用于向网页文本提供标记和样式。
-
{s4} − 它用于动态地与网页布局和内容进行交互并更改它们。
Advantages of AJAX
以下是一些通用网络的优点:
-
它创造了响应式、交互式的网页应用程序。
-
它支持模式和框架的开发,这些模式和框架可以减少开发时间。
-
它充分利用现有技术和功能,而不是使用新技术。
-
它对网络服务器发起异步调用,这意味着客户端不必等待数据到达就开始渲染。
Ajax - History
在 AJAX 引入之前,网站都是通过将多个松散的网页添加在一起开发的,这些网页使用嵌入在 HTML 页面中的链接,进而以预先定义的顺序显示。为了使用这些 Web 应用程序,用户需要在一个网页和另一个网页之间跳转。所以每当用户点击下一页的链接时,他/她应该等待几秒钟才能加载页面。传统的 Web 应用程序使用 HTTP 请求向服务器提交用户操作。在收到用户的请求后,Web 服务器通过返回一个新网页来完成该请求,该网页将在 Web 浏览器上进一步显示。因此,传统的 Web 应用程序需要大量刷新和等待页面。
因此,开发像 Google 地图、实时聊天环境、Gmail 等新一代应用程序非常困难。因此,2005 年 2 月 18 日,Jesse James Garrett 首次通过撰写名为“Web 应用程序的新方法”的 AJAX 文章向世界介绍了 AJAX。2006 年 4 月 5 日,万维网联盟 (W3C) 发表了包含 XMLHttpRequest 对象规范的第一份草案。在那之后,AJAX 开始在 Web 开发者中流行起来。
与传统的 Web 应用程序相比,使用 AJAX 开发的应用程序速度更快、响应性更高。它通过将少量数据交换到 Web 服务器,提高了 Web 应用程序的性能。因此,对于用户的每个请求,服务器都不需要刷新整个网页。这意味着使用 AJAX,Web 浏览器和 Web 服务器可以在后台异步地交换数据,而不会暂停应用程序的执行,并且可以处理返回的数据。为了提交请求,AJAX 应用程序使用一个称为 XMLHttpRequest 对象的特殊对象。这是 AJAX 能够创建异步通信的主要对象。AJAX 中使用的技术有 JavaScript、XMLHttpRequest、XML/JSON 和文档对象模型 (DOM)。JavaScript 在这里处理客户端逻辑,XHR 提供与服务器的异步通信,XML 提供了服务器和客户端之间数据交换的格式,而 DOM 允许处理和更新网页的内容。
Ajax - Dynamic Versus Static Sites
网站是由多个但相关的网页组成的集合,包含多媒体内容,例如文本、图像、视频和音频。互联网上存在的每个网站都有自己的独立 URL,我们可通过网络浏览器访问。例如 - https://www.tutorialspoint.com/ 。
两种类型的网站——
-
Static Website
-
Dynamic Website
Static Website
静态网站是指服务器返回的网页是使用简单的 HTML 和 CSS 编写的预建源代码文件。静态网站的内容是固定的,这意味着网站的内容只能由网站的所有者(手动)更改,允许更改服务器端静态网站的内容。或者我们可以说静态网站是不能从服务器端操作或更改其内容的网站。静态网站不需要任何脚本语言。例如,
Dynamic Website
动态网站是指网页内容是动态的,这意味着网站上的信息可以根据用户给予的输入自动更改。动态网站需要后端数据库和脚本语言,如 PHP、Node.js 等。为获得良好的灵活性,动态网站需要更复杂的后端。动态网站的示例包括 Netflix、Facebook、Twitter 等等。
Dynamic Versus Static Website
以下是动态和静态网站之间的差异——
Static Website |
Dynamic Website |
网站的内容无法在运行时更改。 |
网站的内容可以在运行时更改。 |
不与数据库交互。 |
非常有效地与数据库交互。 |
与动态网站相比,它在网络浏览器上加载得更快。 |
与静态网站相比,它在网络浏览器上加载得更慢。 |
Development cost is cheap. |
Development cost is high. |
它不需要内容管理系统。 |
它需要内容管理系统。 |
它不需要脚本语言。 |
It required scripting languages. |
要开发一个静态网站,我们需要 HTML、CSS 和 Javascript。 |
要开发一个动态网站,除了服务器端语言(例如 PHP、Node.js 等),我们需要 HTML、CSS 和 Javascript 等网络语言。 |
它在每次加载页面时提供相同的数据/内容。 |
它可在每次加载页面时传递不同的内容/数据。 |
It has poor scalability. |
It has good scalability. |
AJAX - Technologies
AJAX 的全称是异步 Javascript 和 XML。它是一组合并了 Web 技术的工具,允许在 Web 服务器和 Web 浏览器之间建立异步通信。它创建了一个动态应用程序,可以在不重新加载整个页面情况下动态更新网页内容。
AJAX 不是一种编程语言或脚本语言,但它结合了多种 Web 相关的技术,例如 HTML、XHTML、CSS、JavaScript、DOM、XML、XSLT 和 XMLHttpRequest 对象。由于这些技术的结合,AJAX 模型允许 Web 开发者创建可以与用户动态交互的 Web 应用程序,并且能够快速向 Web 服务器发出后台调用,以检索所需的应用程序数据,然后更新网页的一小部分,而无需刷新整个网页。
AJAX 不使用任何新语言来创建动态 Web 应用程序,它使用市场上已有的技术。因此,开发人员可以通过 AJAX 模型创建动态 Web 应用程序,而无需学习或安装新技术。因此,AJAX 模型使用以下 Web 技术 −
Javascript −它是一种适用于 HTML 和 Web 应用程序的脚本语言。它建立了 HTML、CSS 和 XML 之间的连接。用于创建客户端功能。它在 AJAX 中也扮演着重要的角色。它还用于创建 AJAX 应用程序或将所有 AJAX 操作联合起来。
<script src = "myexample.js"></script>
XML or JSON −XML 代表可扩展标记语言,而 JSON 代表 JavaScript 对象表示法。JSON 和 XML 都用于客户端来交换 Web 服务器和客户端之间的数据。
<?xml version = "1.0">
<root>
<child>
//Statements
</child>
</root>
XMLHttpRequest −它用于在 Web 浏览器和 Web 服务器之间执行异步数据交换。它是一个执行异步操作的 JavaScript 对象。
variableName = new XMLHttpRequest();
HTML and CSS −HTML 代表超文本标记语言,而 CSS 代表层叠样式表。HTML 对网页文本提供标记和样式。或者可以说它为网页提供了结构,而 CSS 用于创建更多交互式的网页。它提供了定义网页外观的各种样式组件。CSS 独立于 HTML,并且可以与任何基于 XML 的标记语言一起使用。
<!DOCTYPE html>
<html>
<head>
// Header of the web page
</head>
<body>
// Body of the web page
</body>
</html>
DOM - AJAX 还有一个功能强大的工具,称为 DOM(文档对象模型)。它用于交互和动态更改网页布局和内容。或者,我们可以说 DOM 用于创建标记 HTML 页面的元素的逻辑表示。它的提供者是 Web 浏览器。它不是 JavaScript 的一部分,但通过使用 JavaScript,我们可以访问 DOM 对象的方法和属性。通过使用 DOM 方法和属性,我们可以创建或修改 HTML 页面。
<!DOCTYPE html>
<html>
<head>
// Header of the web page
</head>
<body>
<p></p>
<script></script>
</body>
</html>
AJAX - Action
本章使你清楚了解 AJAX 操作的确切步骤。
Steps of AJAX Operation
-
A client event occurs.
-
创建 XMLHttpRequest 对象。
-
对 XMLHttpRequest 对象进行配置。
-
XMLHttpRequest 对象对 Web 服务器发出异步请求。
-
Web 服务器返回包含 XML 文档的结果。
-
XMLHttpRequest 对象调用 callback() 函数并处理结果。
-
更新 HTML DOM。
让我们逐一完成这些步骤。
A Client Event Occurs
-
以事件为结果,调用 JavaScript 函数。
-
例如,将 validateUserId() JavaScript 函数映射为事件处理程序,使其成为输入表单域上的 onkeyup 事件,该输入表单域的 id 设置为 "userid"
-
<input type = "text" size = "20" id = "userid" name = "id" onkeyup = "validateUserId();">.
The XMLHttpRequest Object is Created
var ajaxRequest; // The variable that makes Ajax possible!
function ajaxFunction() {
try {
// Opera 8.0+, Firefox, Safari
ajaxRequest = new XMLHttpRequest();
} catch (e) {
// Internet Explorer Browsers
try {
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
// Something went wrong
alert("Your browser broke!");
return false;
}
}
}
}
The XMLHttpRequest Object is Configured
在此步骤中,我们将编写一个函数,将由客户端事件触发,并且将注册回调函数 processRequest()。
function validateUserId() {
ajaxFunction();
// Here processRequest() is the callback function.
ajaxRequest.onreadystatechange = processRequest;
if (!target) target = document.getElementById("userid");
var url = "validate?id=" + escape(target.value);
ajaxRequest.open("GET", url, true);
ajaxRequest.send(null);
}
Making Asynchronous Request to the Webserver
源代码在上面的代码段中可用。用粗体字书写的代码负责向 Web 服务器发出请求。这一切都是使用 XMLHttpRequest 对象 ajaxRequest 来完成的。
function validateUserId() {
ajaxFunction();
// Here processRequest() is the callback function.
ajaxRequest.onreadystatechange = processRequest;
<b>if (!target) target = document.getElementById("userid");
var url = "validate?id = " + escape(target.value);
ajaxRequest.open("GET", url, true);
ajaxRequest.send(null);</b>
}
假设在 userid 框中输入 Zara,那么在上述请求中,URL 设置为 "validate?id = Zara"。
Webserver Returns the Result Containing XML Document
你可以在任何语言中实现自己的服务器端脚本,但其逻辑应如下所示。
-
获取来自客户端的请求。
-
从客户端解析输入。
-
Do required processing.
-
将输出发送到客户端。
如果我们假设你要编写一个 servlet,那么以下便是部分代码。
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
String targetId = request.getParameter("id");
if ((targetId != null) && !accounts.containsKey(targetId.trim())) {
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
response.getWriter().write("<valid>true</valid>");
} else {
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
response.getWriter().write("<valid>false</valid>");
}
}
Callback Function processRequest() is Called
XMLHttpRequest 对象被配置为在 XMLHttpRequest 对象的 readyState 发生状态更改时调用 processRequest() 函数。现在这个函数将从服务器接收结果,然后执行所需的处理。正如以下示例所示,它根据 Web 服务器返回的值将变量 message 设置为 true 或 false。
function processRequest() {
if (req.readyState == 4) {
if (req.status == 200) {
var message = ...;
...
}
The HTML DOM is Updated
这是最后一步,在这一步中,你的 HTML 页面将被更新。它通过以下方式实现:
-
JavaScript 使用 DOM API 引用页面中的任意元素。
-
获取元素引用的推荐方式是调用 .
document.getElementById("userIdMessage"),
// where "userIdMessage" is the ID attribute
// of an element appearing in the HTML document
-
现在 JavaScript 可用于修改元素的属性,修改元素的样式属性,或添加、移除或修改子元素。以下是一个示例:
<script type = "text/javascript">
<!--
function setMessageUsingDOM(message) {
var userMessageElement = document.getElementById("userIdMessage");
var messageText;
if (message == "false") {
userMessageElement.style.color = "red";
messageText = "Invalid User Id";
} else {
userMessageElement.style.color = "green";
messageText = "Valid User Id";
}
var messageBody = document.createTextNode(messageText);
// if the messageBody element has been created simple
// replace it otherwise append the new element
if (userMessageElement.childNodes[0]) {
userMessageElement.replaceChild(messageBody, userMessageElement.childNodes[0]);
} else {
userMessageElement.appendChild(messageBody);
}
}
-->
</script>
<body>
<div id = "userIdMessage"><div>
</body>
如果你理解了上述七个步骤,那么你几乎已经完成了 AJAX。在下一章,我们将更详细地了解 XMLHttpRequest 对象。
AJAX - XMLHttpRequest
在 AJAX 中,XMLHttpRequest 扮演着非常重要的角色。XMLHttpRequest 用于在后台与 Web 服务器交换数据,而用户/客户端在前台工作,然后使用收到的数据更新网页部分,而无需重新加载整个页面。
我们还可以说,XMLHttpRequest (XHR) 可以由各种 Web 浏览器脚本语言(如 JavaScript、JScript、VBScript 等)使用,通过 HTTP 与 Web 服务器交换 XML 数据。除了 XML 外,XMLHttpRequest 还可以获取各种格式的数据,如 JSON 等。它会在客户端和服务器端之间创建异步连接。
Syntax
variableName = new XMLHttpRequest()
当使用新关键字和 XMLHttpRequest() 构造函数时,我们可以创建一个新的 XMLHttpRequest 对象。必须先创建此对象,然后才能调用 open() 函数对其进行初始化,然后再调用 send() 函数将请求发送到 Web 服务器。
XMLHttpRequest Object Methods
XMLHttpRequest 对象具有以下方法:
Sr.No. |
Method Name & Description |
1 |
new XMLHttpRequest() 用于创建 XMLHttpRequest() 对象 |
2 |
getAllResponseHeaders() 用于获取标头信息 |
3 |
getResponseHeader() 用于获取特定标头信息 |
4 |
open(method, url, async, user, psw) 用于初始化请求参数。此处method:请求类型 GET 或 POST 或其他类型url:文件位置async:异步设置为 true,同步设置为 falseuser:用于可选用户名psw:用于可选密码 |
5 |
send() 用于向 Web 服务器发送请求。它通常用于 GET 请求。 |
6 |
send(string) 用于向服务器发送请求。它通常用于 POST 请求。 |
7 |
setRequestHeader() 用于向标头添加键/值对 |
XMLHttpRequest Object Properties
XMLHttpRequest 对象具有以下属性:
Sr.No. |
Property Name & Description |
1 |
onreadystatechange 设置处理请求状态更改的回调函数。 |
2 |
readyState 用于保存 XMLHttpRequest 的状态。它具有以下值:- 它表示未初始化请求- 它表示已建立服务器连接- 它表示已收到请求- 它表示正在处理请求- 它表示请求已完成且响应已准备就绪 |
3 |
responseText 用于以字符串形式返回响应数据 |
4 |
responseXML 用于将响应数据作为 XML 数据返回 |
5 |
Status 用于返回请求的状态号。例如:- 200:确定- 403:禁止- 404:未找到 |
6 |
StatusText 它用于返回状态文本。例如,OK、未找到等。 |
Usage of XMLHttpRequest
在了解了 XMLHttpRequest 的基本语法、方法和属性之后,现在我们学习如何实际使用 XMLHttpRequest。因此,要在您的程序中使用 XMLHttpRequest,首先我们需要遵循以下主要步骤 −
Step 1 − 创建 XMLHttpRequest 对象
var variableName = new XMLHttpRequest()
Step 2 − 在创建 XMLHttpRequest 对象后,我们现在必须定义一个回调函数,该函数将在从 Web 服务器获取响应后触发。
XMLHttpRequestObjectName.onreadystatechange = function(){
// Callback function body
}
XMLHttpRequestObjectName.open(method, url, async)
XMLHttpRequestObjectName.send()
Step 3 − 现在我们使用 open() 和 send() 函数向 Web 服务器发送请求。
现在让我们在以下示例的帮助下了解 XMLHttpRequest 的工作原理 −
Example
在下面的示例中,我们将从服务器获取数据。要从服务器获取数据,我们将单击“单击我”按钮。因此,当我们单击“单击我”按钮时,将调用 displayDoc() 函数。在 displayDoc() 函数中,我们创建一个 XMLHttpRequest 对象。然后,我们创建一个回调函数来处理服务器响应。然后,我们调用 XHR 对象的 open() 方法,使用 HTTP GET 方法和服务器 URL 来初始化请求,网址为 "https://jsonplaceholder.typicode.com/todos" 。然后我们调用 send() 函数来发送请求。
因此,当服务器响应请求时,“onreadystatechange”属性会使用 XMLHttpRequest 对象的当前状态调用回调函数。如果“就绪状态”属性设置为 4(意味着请求已完成),并且“状态”属性设置为 200(意味着响应成功),则响应数据将从“responseText”属性中提取,并使用“innerHTML”属性显示 HTML 文档示例元素的。
如果在请求过程中发现错误,则回调函数中存在的 else 语句将执行。因此,这就是我们从服务器获取数据的方式。
<!DOCTYPE html>
<html>
<body>
<script>
function displayDoc() {
// Creating XMLHttpRequest object
var myObj = new XMLHttpRequest();
// Creating a callback function
myObj.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("sample").innerHTML = this.responseText;
}else{
console.log("Error Found")
}
};
// Open the given file
myObj.open("GET", "https://jsonplaceholder.typicode.com/todos", true);
// Sending the request to the server
myObj.send();
}
</script>
<div id="sample">
<h2>Getting Data</h2>
<p>Please click on the button to fetch data</p>
<button type="button" onclick="displayDoc()">Click Me</button>
</div>
</body>
</html>
AJAX - Sending Request
AJAX 应用程序使用 XMLHttpRequest 对象以非常有效的方式启动或管理发送到 Web 服务器的数据请求,并处理或监控 Web 服务器发送的数据。AJAX 支持以下类型的请求:
-
GET request
-
POST request
-
PUT request
-
DELETE request
要创建连接并向 Web 服务器发送请求,XMLHttpRequest 对象提供了以下两种方法:
open() − 用于在 Web 浏览器与 Web 服务器之间创建连接。
send() − 用于向 Web 服务器发送请求。
Syntax
open(method, url, async)
其中,open() 方法接受三个参数:
-
method − 它表示用于与 Web 服务器建立连接的 HTTP 方法(GET 或 POST)。
-
url − 它表示将在 Web 服务器上打开的文件 URL。或者我们可以说服务器(文件)位置。
-
async − 对于异步连接,将值设置为 true。或者对于同步连接,将值设置为 false。此参数的默认值为 true。
要使用`open()`方法,我们首先创建一个 XMLHttpRequest 对象的实例。然后我们调用`open()`方法以使用 HTTP GET 或 POST 方法和服务器 URL 来初始化请求。
GET 选项用于从 Web 服务器检索适量的信息,而 POST 选项用于检索更多信息。所以 GET 和 POST 选项都可以配置 XMLHttpRequest 对象以使用给定的文件。
在 open() 方法中,可以使用绝对路径或相对路径指定 AJAX 应用程序的文件名、位置或路径。其中绝对路径是指定文件的确切位置的路径,例如 −
Myrequest.open("GET", "http://www.tutorialspoint.com/source.txt")
此处“source.txt”是文件名, "http://www.tutorialspoint.com" 是存储 source.txt 文件的位置。
相对路径用于根据 Web 服务器上的位置相对于 Web 应用程序文件指定文件的位置,例如 −
Myrequest.open("GET", "my file.txt")
Sending Request
要向服务器发送请求,首先需要创建 XMLHttpRequest 对象的实例,然后创建一个回调函数,此函数将在从 Web 服务器获得响应后生效。然后,我们使用 open() 方法建立 Web 浏览器和 Web 服务器之间的异步连接,然后使用 send() 函数向服务器发送请求。
Example
在以下代码中,我们正在从服务器获取指定的记录。要从服务器获取数据,请单击“单击此处”按钮。所以当我们单击“单击此处”按钮时,showDoc() 函数被调用。在 displayDoc() 函数内部,首先创建 XMLHttpRequest 对象。然后,我们创建一个回调函数来处理服务器响应。然后,我们调用 XHR 对象的 open() 方法以使用 HTTP GET 方法和服务器 URL 初始化请求,即 "https://jsonplaceholder.typicode.com/todos/3" ,该 URL 从 JSONPlaceholder API 中获取一个 ID = 3 的待办事项列表。然后,我们调用 send() 函数来发送请求。
<!DOCTYPE html>
<html>
<body>
<script>
function ShowDoc() {
// Creating XMLHttpRequest object
var myhttp = new XMLHttpRequest();
// Creating call back function
myhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("example").innerHTML = this.responseText;
}
};
// Open the given file
myhttp.open("GET", "https://jsonplaceholder.typicode.com/todos/3", true);
// Sending the request to the server
myhttp.send();
}
</script>
<div id="example">
<p>Please click on the button to fetch data</p>
<button type="button" onclick="ShowDoc()">Click Here</button>
</div>
</body>
</html>
AJAX - Types of Requests
AJAX 是一种用于创建动态网页的 Web 技术。它允许网页更新其内容,而无需重新加载整个页面。总体而言,AJAX 支持四种类型的请求,它们是:
-
GET request
-
POST request
-
PUT request
-
DELETE request
Syntax
open(GET, url, true)
其中,open() 方法接受三个参数:
-
GET - 用于从服务器检索数据。
-
url - url 表示将在 Web 服务器上打开的文件。
-
true - 对于异步连接,将值设置为 true。或者,对于同步连接,将值设置为 false。此参数的默认值为 true。
Example
<!DOCTYPE html>
<html>
<body>
<script>
function displayRecords() {
// Creating XMLHttpRequest object
var zhttp = new XMLHttpRequest();
// Creating call back function
zhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("example").innerHTML = this.responseText;
}
};
// Open the given file
zhttp.open("GET", "https://jsonplaceholder.typicode.com/todos/6", true);
// Sending the request to the server
zhttp.send();
}
</script>
<div id="example">
<p>Please click on the button to fetch 6th record from the server</p>
<button type="button" onclick="displayRecords()">Click Here</button>
</div>
</body>
</html>
Output
在上面的示例中,我们使用 XMLHttpRequest 中的 GET 请求 "https://jsonplaceholder.typicode.com/todos/6" API 从服务器获取第 6 条记录。因此,单击按钮后,我们将在服务器中获取第 6 条记录。
Syntax
open('POST', url, true)
其中,open() 方法接受三个参数:
-
POST − 它用于向 Web 服务器发送数据。
-
url − url 表示服务器(文件)位置。
-
true - 对于异步连接,将值设置为 true。或者,对于同步连接,将值设置为 false。此参数的默认值为 true。
Example
<!DOCTYPE html>
<html>
<body>
<script>
function sendDoc() {
// Creating XMLHttpRequest object
var qhttp = new XMLHttpRequest();
// Creating call back function
qhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 201) {
document.getElementById("sample").innerHTML = this.responseText;
console.log("Data Send Successfully")
}
};
// Open the given file
qhttp.open("POST", "https://jsonplaceholder.typicode.com/todos", true);
// Setting HTTP request header
qhttp.setRequestHeader('Content-type', 'application/json')
// Sending the JSON document to the server
qhttp.send(JSON.stringify({
"title": "MONGO",
"userId": 11,
"id": 21,
"body": "est rerum tempore"
}));
}
</script>
<h2>Example of POST Request</h2>
<button type="button" onclick="sendDoc()">Post Data</button>
<div id="sample"></div>
</body>
</html>
Output
在上述示例中,我们使用 PUT 请求使用以下给定数据更新记录。
"https://jsonplaceholder.typicode.com/todos/21" API:
{
"title": "MONGO",
"userId": 11,
"id": 21,
"body": "est rerum tempore"
}
Syntax
open('DELETE', url, true)
其中,open() 方法接受三个参数:
-
DELETE − 它用于从 Web 服务器中删除数据。
-
url − 它表示将在 Web 服务器上打开的文件 URL。或者我们可以说服务器(文件)位置。
-
true - 对于异步连接,将值设置为 true。或者,对于同步连接,将值设置为 false。此参数的默认值为 true。
Example
<!DOCTYPE html>
<html>
<body>
<script>
function delDoc() {
// Creating XMLHttpRequest object
var qhttp = new XMLHttpRequest();
// Creating call back function
qhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("sample").innerHTML = this.responseText;
console.log("Record Deleted Successfully")
}
};
// Deleting given file
qhttp.open("DELETE", "https://jsonplaceholder.typicode.com/todos/2", true);
// Sending the request to the server
qhttp.send();
}
</script>
<div id="sample">
<h2>Example of DELETE Request</h2>
<button type="button" onclick="delDoc()">Deleteing Data</button>
</div>
</body>
</html>
Output
在上述示例中,我们使用 DELETE 请求 "https://jsonplaceholder.typicode.com/todos/2" API 删除 Id = 2 上的记录。
AJAX 还支持其他一些请求,例如 OPTIONS、HEAD 和 TRACE,但它们是 AJAX 应用程序最不常用的请求。现在在下一篇文章中,我们将看到 AJAX 如何处理响应。
AJAX - Handling Responses
AJAX 是一种用于在不重新加载或刷新整页的情况下,与 web 服务器异步发送和接收数据的技术。当 AJAX 应用程序从一个网页向服务器发出一个异步请求时,服务器对该请求作出响应并返回被请求的数据,因此,接收和处理服务器的响应称为处理响应。或者我们可以说,处理响应是一个处理服务器返回的数据、对其执行适当的操作并相应地更新网页的过程。
处理响应包括以下几个方面:
Receiving Response − 一旦 AJAX 向服务器发送了请求,客户端 JS 代码便等待服务器响应。当服务器响应该请求时,响应将返回给客户端。
Process Response − 从服务器获取响应后,客户端 JS 会处理预期格式的数据,因为服务器返回的数据采用 JSON、XML 等多种格式,并且还只从响应中提取相关的信息。
Updateding Web application/ web page − 处理响应后,AJAX 回调函数会根据响应动态更新网页或 web 应用程序。这包括修改 HTML 内容、显示错误消息、更新值等等。
Handle Error − 如果该请求遇到错误,那么由于任何请求失败、网络问题等原因,服务器可能会响应一个错误状态。因此,处理响应的过程非常有效地处理错误,并对错误采取适当的措施。
How to handle responses works
按照以下步骤使用 XMLHttpRequest 处理响应:
Step 1 − 使用 XMLHttpRequest() 构造函数创建一个 XMLHttpRequest 对象。使用该对象,你可以轻松地执行 HTTP 请求,并可以异步处理它们的响应。
var qhttp = new XMLHttpRequest();
Step 2 − 为 readystatechange 事件定义一个事件处理程序。当 XHR 对象的 readyState 属性的值发生更改时,会触发该事件。
qhttp.onreadystatechange = function() {
if (qhttp.readyState == 4){
if(qhttp.status == 200){
// Display the response
}else{
// Handle the error if occure
}
}
};
Step 3 − 使用 HTTP 方法(如 GET、POST 等)和我们要请求的 URL 来打开该请求。
qhttp.open("HTTP Method","your-URL", true);
Step 4 − 根据需要设置任何标头。
qhttp.setRequestHeader('Authorization', 'Your-Token');
Step 5 − 向服务器发送该请求。
qhttp.send()
Example
在以下程序中,我们将处理服务器在给定请求上返回的响应。因此,我们要创建一个名为 handleResponse() 的 JavaScript 函数,它负责处理服务器返回的响应并相应地显示结果。该函数首先创建一个 XMLHttpRequest 对象,然后定义一个 “onreadystatechange” 事件处理程序来处理请求状态。当请求状态发生更改时,该函数会检查该请求是否已完成(readyState = 4)。如果该请求已完成,则函数会检查状态代码是否为 200。如果状态代码为 200,则显示该响应。否则,则显示错误消息。
<!DOCTYPE html>
<html>
<body>
<script>
function handleResponse() {
// Creating XMLHttpRequest object
var qhttp = new XMLHttpRequest();
// Creating call back function
qhttp.onreadystatechange = function() {
if (qhttp.readyState == 4){
if(qhttp.status == 200){
// Display the response
console.log(qhttp.responseText)
}else{
console.log("Found Error: ", qhttp.status)
}
}
};
// Open the given file
qhttp.open("GET", "https://jsonplaceholder.typicode.com/todos", true);
// Sending request to the server
qhttp.send()
}
</script>
<h2>Display Data</h2>
<button type="button" onclick="handleResponse()">Submit</button>
<div id="sample"></div>
</body>
</html>
AJAX - Handling Binary Data
二进制数据是格式为二进制而不是文本的。它包括图像、音频、视频和其他非纯文本文件。我们可以使用 XMLHttpRequest 对象在 AJAX 中发送和接收二进制数据。在 AJAX 中使用二进制数据时,设置一个正确的容器类型和响应类型标头非常重要。因此,要设置标头,我们使用“Content-Type”标头,此处我们将正确的 MIME 类型设置为发送二进制数据,并将“responseType”属性设置为“arraybuffer”或“blob”,表示接收二进制数据。
Sending Binary Data
要发送二进制数据,我们使用 XMLHttpRequest 的 send() 方法,该方法可以使用 ArrayBuffer、Blob 或 File 对象轻松传输二进制数据。
Example
在以下程序中,我们创建了一个将从服务器接收二进制数据的程序。所以当我们单击按钮 getBinaryData() 函数触发器时。它使用 XMLHttpRequest 对象利用 GET 方法从给定 URL 获取数据。在此函数中,我们将 responseType 属性设置为 arraybuffer,它告诉浏览器我们只需要在响应中接受二进制数据。请求完成后,将调用 onload() 函数,在此函数中,我们检查请求的状态,如果响应成功,则响应被视为 arraybuffer。然后,使用 Unit8Array() 函数将 arraybuffer 转换成 Uint8array。它访问二进制数据的各个字节。之后,我们将在 HTML 页面上显示数据。
<!DOCTYPE html>
<html>
<body>
<script>
function getBinaryData() {
// Creating XMLHttpRequest object
var myhttp = new XMLHttpRequest();
// Getting binary data
myhttp.open("GET", "https://jsonplaceholder.typicode.com/posts", true);
// Set responseType to arraybuffer.
myhttp.responseType = "arraybuffer";
// Creating call back function
myhttp.onload = (event) => {
// IF the request is successful
if (myhttp.status === 200){
var arraybuffer = myhttp.response;
// Convert the arraybuffer into array
var data = new Uint8Array(arraybuffer);
// Display the binary data
document.getElementById("example").innerHTML = data;
console.log("Binary data Received");
}else{
console.log("Found error");
}
};
// Sending the request to the server
myhttp.send();
}
</script>
<div id="example">
<p>AJAX Example</p>
<button type="button" onclick="getBinaryData()">Click Here</button>
</div>
</body>
</html>
AJAX - Submitting Forms
AJAX 是最为流行的 Web 技术,几乎所有 Web 开发者都使用它来创建动态 Web 应用程序。它利用 Web 浏览器内置的 XMLHttpRequest 对象在后台将数据异步地发送至 Web 服务器或从 Web 服务器接收数据,而无需刷新或影响网页。我们还能利用 AJAX 轻松地提交表单。
所以,要使用 AJAX 提交表单,我们需要遵循以下步骤:
Step 1 − 使用 XMLHttpRequest() 构造函数创建一个 XMLHttpRequest 对象;
var zhttp = new XMLHttpRequest();
Step 2 − 创建一个变量(也称为表单元素),它包含使用 document.querySelector() 方法在表单中显示的所有键值对。
const FormElement = document.querySelector("mForm")
此处,如果你有多个表单,那么可以用其 ID 定义表单。
Step 3 − 使用 FormData 构造函数创建一个 FormData 对象,并将其传递到上述创建的 FormElement 中。这意味着 FormData 对象使用键值对初始化。
const myForm = new FormData(FormElement)
Step 4 − 创建一个将在服务器响应请求时执行的回调函数。此函数在 XHR 对象的 onreadystatechange 属性内定义。
zhttp.onreadystatechange = function() {
// Body
}
此处,responseText 属性将以 JavaScript 字符串的形式返回服务器的响应,我们将在网页中进一步使用它来显示消息。
document.getElementById("responseElement").innerHTML = this.responseText;
Step 5 − 现在我们使用 open() 函数。在 open() 函数内部,我们将 POST 请求与我们必须将表单数据发送到的 URL 一起传递。
zhttp.open("POST", url, async)
Step 6 − 最后,我们使用 send() 函数将请求连同 FormData 对象一起发送到服务器。
zhttp.send(myForm);
因此,完整示例如下:
Example
在上面的代码中,我们创建了一个简单的 HTML 表单来收集用户数据,然后使用 XMLHttpRequest 和 JavaScript 提交表单数据。
因此,当用户单击“提交记录”按钮时,将调用 sendFormData() 函数。sendFormData() 函数首先创建一个新的 XHR 对象。然后,创建一个表单元素来存储 HTML 表单中的所有键值对。然后,它是一个新的 FormData 对象,并将表单元素传递到对象中。接下来,它设置了一个回调函数来处理来自服务器的响应。当 readyState 属性的值 = 4 且 Status 属性的值 = 201 时,将触发此函数。最后,它调用 open() 方法并使用服务器 URL 初始化 HTTP POST 方法,最后调用 send() 方法将 FormData 请求发送到服务器。
因此,当来自服务器的响应时,回调函数将显示结果并在控制台日志中打印消息。
<!DOCTYPE html>
<html>
<body>
<script>
function sendFormData() {
// Creating XMLHttpRequest object
var zhttp = new XMLHttpRequest();
const mFormEle = document.querySelector("#mForm")
// Creating FormData object
const myForm = new FormData(mFormEle);
// Creating call back function to handle the response
zhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 201) {
document.getElementById("example").innerHTML = this.responseText;
console.log("Form Data Posted Successfully")
}
};
// Post/Add form data on the server
zhttp.open("POST", "https://jsonplaceholder.typicode.com/todos", true);
// Sending the request to the server
zhttp.send(new FormData(mFormEle));
}
</script>
<!--Creating simple form-->
<form id = "mForm">
<h2>Enter the requested Data</h2>
<label for="Utitle">Title</label>
<input id="Utitle" type="text" name="title"><br>
<label for="UId">UserId</label>
<input id="UId" type="number" name="UserID"><br>
<label for="Ubody">Body</label>
<input id="Ubody" type="text" name="body"><br>
<label for="Uage">Age</label>
<input id="Uage" type="number" name="age"><br>
<button type="button" onclick="sendFormData()">Submit Record</button>
</form>
<div id="example"></div>
</body>
</html>
AJAX - File Uploading
AJAX 提供了一种创建可将文件上传到服务器的 HTTP 请求的灵活方法。我们可以使用 FormData 对象在请求中发送单个或多个文件。让我们借助以下示例来讨论此概念 −
Example − Uploading a Single File
在以下示例中,我们将使用 XMLHttpRequest 上传单个文件。因此,首先我们创建一个简单的表单,其中包含一个文件上传按钮和一个提交按钮。现在,我们在 JavaScript 中编写代码,在其中我们获取表单元素并在单击上传文件按钮时创建触发器的事件。在此事件中,我们将上传的文件添加到 FormData 对象中,然后创建一个 XMLHttpRequest 对象,该对象将使用 FormData 对象将文件发送到服务器,并处理服务器返回的响应。
<!DOCTYPE html>
<html>
<body>
<!-- Creating a form to upload a file-->
<form id = "myForm">
<input type="file" id="file"><br><br>
<button type="submit">Upload File</button>
</form>
<script>
document.getElementById('myForm').addEventListener('submit', function(x){
// Prevent from page refreshing
x.preventDefault();
// Select the file from the system
// Here we are going to upload one file at a time
const myFile = document.getElementById('file').files[0];
// Create a FormData to store the file
const myData = new FormData();
// Add file in the FormData
myData.append("newFiles", myFile);
// Creating XMLHttpRequest object
var myhttp = new XMLHttpRequest();
// Callback function to handle the response
myhttp.onreadystatechange = function(){
if (myhttp.readyState == 4 && myhttp.status == 200) {
console.log("File uploaded Successfully")
}
};
// Open the connection with the web server
myhttp.open("POST", "https://httpbin.org/post", true);
// Setting headers
myhttp.setRequestHeader("Content-Type", "multipart/form-data");
// Sending file to the server
myhttp.send(myData);
})
</script>
</body>
</html>
Example − Uploading Multiple Files
在以下示例中,我们将使用 XMLHttpRequest 上传多个文件。这里我们在 DOM 中从具有文件类型属性的系统中选择两个文件。然后我们将输入文件添加到一个数组中。然后我们创建一个 FormData 对象并将输入文件附加到该对象。然后我们创建一个 XMLHttpRequest 对象,该对象将使用 FormData 对象将文件发送到服务器,并处理服务器返回的响应。
<!DOCTYPE html>
<html>
<body>
<!-- Creating a form to upload multiple files-->
<h2> Uploading Multiple files</h2>
<input type="file">
<input type="file">
<button>Submit</button>
<script>
const myButton = document.querySelector('button');
myButton.addEventListener('click', () => {
// Get all the input files in DOM with attribute type "file":
const inputFiles = document.querySelectorAll('input[type="file"]');
// Add input files in the array
const myfiles = [];
inputFiles.forEach((inputFiles) => myfiles.push(inputFiles.files[0]));
// Creating a FormData
const myformdata = new FormData();
// Append files in the FormData object
for (const [index, file] of myfiles.entries()){
// It contained reference name, file, set file name
myformdata.append(`file${index}`, file, file.name);
}
// Creating an XMLHttpRequest object
var myhttp = new XMLHttpRequest();
// Callback function
// To handle the response
myhttp.onreadystatechange = function(){
if (myhttp.readyState == 4 && myhttp.status == 200) {
console.log("File uploaded Successfully")
}
};
// Open the connection with the web server
myhttp.open("POST", "https://httpbin.org/post", true);
// Setting headers
myhttp.setRequestHeader("Content-Type", "multipart/form-data");
// Sending file to the server
myhttp.send(myformdata);
})
</script>
</body>
</html>
AJAX - FormData Object
在 AJAX 中,FormData 对象允许您创建一组代表表单字段及其值(可以使用 XMLHttpRequest 发送)的键值对。它主要用于发送表单数据,但也可以独立发送数据。由 FormData 对象传输的数据与由表单的“提交”方法发送的数据具有相同格式。
要创建新的 FormData 对象,AJAX 提供 FormData() 构造函数。
Syntax
const objectName = new FormData()
Or
const objectName = new FormData(form)
Or
const objectName = new FormData(form, mSubmit)
其中 FormData() 可以带或不带参数使用。FormData() 构造函数使用的可选参数为:
form − 它代表 HTML <form> 元素。如果 FormData 对象有此参数,那么该对象将使用每个元素的 name 属性(作为键)及其提交的值来填充表单当前的键值对。它还会对文件的输入内容进行编码。
mSubmit − 它表示表单的提交按钮。如果 mSubmit 有 name 属性或 <input type = "image>,那么其内容将包含在 FormData 对象中。如果指定的 mSubmit 不是按钮,那么它将引发 TypeError 异常。如果 mSubmit 不是给定表单的成员,那么它将引发 NotFoundError。
Methods
FormData 对象支持以下方法:
Sr.No. |
Method Name & Description |
1 |
FormData.append() 此方法用于将新值附加到现有键中。或者,可以在不存在时添加新键。 |
2 |
FormData.delete() 此方法用于删除键值对。 |
3 |
FormData.entries() 此方法返回一个迭代器,在键值对中进行迭代。 |
4 |
FormData.get() 此方法从 FormData 对象返回与给定键相关的第一值。 |
5 |
FormData.getAll() 此方法用于返回 FormData 对象中与给定的键相关的所有值的数组。 |
6 |
FormData.has() 此方法检查 FormData 对象是否包含指定的键。 |
7 |
FormData.keys() 此方法返回一个迭代器,在 FormData 对象中存在的键值对的所有键中进行迭代。 |
8 |
FormData.set() 此方法为 FormData 对象中的现有键设置新的值。或者,可以在不存在时添加新的键/值。 |
9 |
FormData.values() 此方法返回一个迭代器,在 FormData 对象中存在的所有值中进行迭代。 |
Creating FormData Object
在没有 HTML 表单的情况下创建和使用 FormData 对象,请执行以下步骤:
Step 1 − 使用 XMLHttpRequest() 构造函数创建一个 XMLHttpRequest 对象;
var zhttp = new XMLHttpRequest();
Step 2 - 使用 FormData 构造函数创建 FormData 对象:
const myForm = new FormData()
Step 3 - 使用 append() 方法添加键值对:
myForm.append("KeyName", "keyValue")
Step 4 - 创建回调函数来处理响应:
zhttp.onreadystatechange = function() {
// Body
}
Step 5 - 现在我们使用 open() 函数。在 open() 函数内部,我们传递一个 POST 请求以及我们要发布表单数据的服务器 URL。
zhttp.open("POST", url, async)
Step 6 - 因此,最后我们使用 send() 函数将请求和 FormData 对象一起发送到服务器。
zhttp.send(myForm);
现在,让我们借助示例来讨论这一点:
Example 1
<!DOCTYPE html>
<html>
<body>
<script>
function dataDoc() {
// Creating XMLHttpRequest object
var zhttp = new XMLHttpRequest();
// Creating FormData object
const myForm = new FormData();
// Assigning the form data object with key/value pair
myForm.append("title", "AJAX Tutorial")
myForm.append("UserId", "232")
myForm.append("Body", "It is for web development")
myForm.append("Age", "33")
// Creating call back function to handle the response
zhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 201) {
document.getElementById("example").innerHTML = this.responseText;
console.log("Form Data Posted Successfully")
}
};
// Specify the method as POST, URL, and set async to true
zhttp.open("POST", "https://jsonplaceholder.typicode.com/todos", true);
// Sending the request to the server
zhttp.send(myForm);
}
</script>
<h2>Sending Form Data</h2>
<button type="button" onclick="dataDoc()">Submit</button>
<div id="example"></div>
</body>
</html>
Output
因此,当用户单击“提交”按钮时,将调用 dataDoc() 函数。然后,dataDoc() 函数首先创建新的 XHR 对象和新的 FormData 对象。然后,使用 append() 方法在 FormData 对象中添加新的键值对。接下来,它设置了处理来自服务器的响应的回调函数。当 readyState 属性的值 = 4 且 Status 属性的值 = 201 时,将触发此函数。最后,它调用 open() 方法并使用服务器的 URL 通过 HTTP POST 方法对其进行初始化,最后它调用 send() 方法将 FormData 请求发送到服务器。
因此,当响应来自服务器时,回调函数将显示结果并在控制台日志中打印“表单数据已成功发布”消息。
Example 2
<!DOCTYPE html>
<html>
<body>
<script>
function sendFormData() {
// Creating XMLHttpRequest object
var zhttp = new XMLHttpRequest();
// Creating FormData object
const myForm = new FormData();
// Assigning the form data with key/value pair
myForm.append("title", document.querySelector('#Utitle').value)
myForm.append("UserId", document.querySelector('#UId').value)
myForm.append("Body", document.querySelector('#Ubody').value)
myForm.append("Age", document.querySelector('#Uage').value)
// Creating call back function to handle the response
zhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 201) {
document.getElementById("example").innerHTML = this.responseText;
console.log("Form Data Posted Successfully")
}
};
// Post/Add form data on the server
zhttp.open("POST", "https://jsonplaceholder.typicode.com/todos", true);
// Sending the request to the server
zhttp.send(myForm);
}
</script>
<!--Creating simple form-->
<h2>Enter the requested Data</h2>
<label for="Utitle">Title</label>
<input id="Utitle" type="text" name="title"><br>
<label for="UId">UserId</label>
<input id="UId" type="number" name="UserID"><br>
<label for="Ubody">Body</label>
<input id="Ubody" type="text" name="body"><br>
<label for="Uage">Age</label>
<input id="Uage" type="number" name="age"><br>
<button type="button" onclick="sendFormData()">Submit Record</button>
<div id="example"></div>
</body>
</html>
Output
在下图中,在输入详细信息后,当我们单击“提交”按钮时,数据将发送到服务器,服务器返回 ID 并在控制台中显示消息。
在上面的代码中,我们从用户那里收集数据,并使用 JavaScript 与 XMLHttpRequest 提交数据。
因此,当用户单击“提交记录”按钮时,将调用 sendFormData() 函数。sendFormData() 函数首先创建新的 XHR 对象和新的 FormData 对象。它追加使用 append() 方法由用户输入的键及其值的表单数据。接下来,它设置了处理来自服务器的响应的回调函数。当 readyState 属性的值 = 4 且 Status 属性的值 = 201 时,将触发此函数。最后,它调用 open() 方法并使用服务器的 URL 通过 HTTP POST 方法对其进行初始化,最后它调用 send() 方法将 FormData 请求发送到服务器。
来自服务器的响应,回调函数显示结果并在控制台日志中打印消息。
AJAX - Send POST Requests
POST 请求将数据从网页发送到 Web 服务器。在此请求中,数据以与 URL 分离的请求正文形式发送。您无法缓存和书签 POST 请求。此外,使用 POST 请求,您可以获得任何长度的数据。
Syntax
open('POST', url, true)
此方法需要三个参数,它们是:
-
POST − 它用于向 Web 服务器发送数据。
-
url - 它表示将在 Web 服务器上打开的文件 URL。
-
true - 对于异步连接,将此参数的值设置为 true。或者,对于同步连接,将值设置为 false。此参数的默认值为 true。
How to use POST Request
要使用 POST 请求,我们需要执行以下步骤:
Step 1 − 创建 XMLHttpRequest 对象。
var variableName = new XMLHttpRequest()
Step 2 − 创建 XMLHttpRequest 对象后,我们现在必须定义一个回调函数,该函数将在从 Web 服务器得到响应后触发。
XMLHttpRequestObjectName.onreadystatechange = function(){
// Callback function body
}
Step 3 − 现在我们使用 open() 函数。在 open() 函数中,我们传入一个 POST 请求以及要向其发送数据的 URL。
XMLHttpRequestObjectName.open("POST", url, async)
XMLHttpRequestObjectName.setRequestHeader('Content-type', 'application/json')
Step 4 − 使用 setRequestHeader() 设置 HTTP 标头请求。它总是先调用 open() 方法后调用 send() 方法。这里内容类型标头设置为“application/json”,表示要以 JSON 格式发送数据。
Step 5 − 最后,我们使用 stringify() 方法将 JSON 数据转换为字符串,然后使用 send() 方法将其发送到 Web 服务器。
XMLHttpRequestObjectName.send(JSON.stringify(JSONdata))
以下流程图将显示下方代码的工作原理 −
Example
<!DOCTYPE html>
<html>
<body>
<script>
function sendRecords() {
// Creating XMLHttpRequest object
var zhttp = new XMLHttpRequest();
// JSON document
const mParameters = {
title: document.querySelector('#Utitle').value,
userid: document.querySelector('#UId').value,
body: document.querySelector('#Ubody').value
}
// Creating call back function
zhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 201) {
document.getElementById("example").innerHTML = this.responseText;
console.log("Data Posted Successfully")
}
console.log("Error found")
};
// Post/Add JSON document on the given API
zhttp.open("POST", "https://jsonplaceholder.typicode.com/todos", true);
// Setting HTTP request header
zhttp.setRequestHeader('Content-type', 'application/json')
// Sending the request to the server
zhttp.send(JSON.stringify(mParameters));
}
</script>
<!--Creating simple form-->
<h2>Enter data</h2>
<label for="Utitle">Title</label>
<input id="Utitle" type="text" name="title"><br>
<label for="UId">UserId</label>
<input id="UId" type="number" name="UserID"><br>
<label for="Ubody">Body</label>
<input id="Ubody" type="text" name="body"><br>
<button type="button" onclick="sendRecords()">Submit</button>
<div id="example"></div>
</body>
</html>
使用 HTTP POST 方法和服务器的 URL 初始化请求,即 "https://jsonplaceholder.typicode.com/todos" 。然后我们调用 setRequestHeader() 方法来将请求的内容类型设置为 JSON。在那之后,我们调用 send() 函数以字符串形式向服务器发送请求和 JSON 文档。
因此,当服务器对请求做出响应时,“onreadystatechange”属性使用 XMLHttpRequest 对象的当前状态调用回调函数。如果“准备状态”属性设置为 4(这意味着请求已完成)并且“状态”属性设置为 201(这意味着服务器已成功创建新资源),则从“responseText”属性中提取响应数据,并借助示例元素的“innerHTML”属性显示 HTML 文档。
此处使用 JSON.stringify() 方法将 JSON 文档转换为字符串。这是必需的,因为 XHR 请求只能发送文本数据。
AJAX - Send PUT Requests
PUT 请求用于更新 Web 服务器上的数据。在此请求中,数据在请求正文中发送,并且 Web 服务器会用新数据替换现有数据。如果指定数据不存在,则它会将替换数据作为新记录添加到服务器中。
PUT 请求在以下几方面与 POST 请求有很大不同 −
-
PUT 用于更新现有记录,而 POST 用于向服务器添加新记录。
-
PUT 请求可以被缓存,而 POST 请求不能被缓存。
-
PUT 请求是幂等的,而 POST 请求不是幂等的。
-
PUT 请求作为特定的请求,而 POST 请求作为抽象的请求。
Syntax
open('PUT', url, true)
其中,open() 方法接受三个参数:
-
PUT − 它用于更新 Web 服务器上的数据。
-
url − url 表示将在 Web 服务器上打开的文件 url 或位置。
-
true - 对于异步连接,将值设置为 true。或者,对于同步连接,将值设置为 false。此参数的默认值为 true。
How to send PUT Request
若要发送 PUT 请求,我们需要遵循以下步骤−
Step 1 − 创建 XMLHttpRequest 对象。
var variableName = new XMLHttpRequest()
Step 2 − 创建 XMLHttpRequest 对象后,我们现在必须定义一个回调函数,该函数将在从 Web 服务器得到响应后触发。
XMLHttpRequestObjectName.onreadystatechange = function(){
// Callback function body
}
XMLHttpRequestObjectName.setRequestHeader('Content-type', 'application/json')
Step 4 − 使用 setRequestHeader() 设置 HTTP 头部请求。它总是在 open() 方法之后调用,但在 send() 方法之前调用。在此处,content-type 头部设置为 "application/json",这表示数据将以 JSON 格式发送。
Step 5 − 最后,我们使用 stringify() 方法将 JSON 数据转换为字符串,然后使用 send() 方法将其发送到 Web 服务器以更新服务器上存在的数据。
XMLHttpRequestObjectName.send(JSON.stringify(JSONdata))
以下流程图将显示该示例的工作原理−
Example
<!DOCTYPE html>
<html>
<body>
<script>
function updateDoc() {
// Creating XMLHttpRequest object
var uhttp = new XMLHttpRequest();
// Creating call back function
uhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("sample").innerHTML = this.responseText;
console.log("Data update Successfully")
}
};
// Updating the given file
uhttp.open("PUT", "https://jsonplaceholder.typicode.com/todos/21", true);
// Setting HTTP request header
uhttp.setRequestHeader('Content-type', 'application/json')
// Sending the JSON document to the server
uhttp.send(JSON.stringify({
"title": "ApplePie",
"userId": 12,
"id": 32,
"body": "ApplePie is made up of Apple"
}));
}
</script>
<h2>PUT Request</h2>
<button type="button" onclick="updateDoc()">Updating Record</button>
<div id="sample"></div>
</body>
</html>
Output
在单击更新按钮后,服务器返回的输出。
在此处,在上述代码中,我们正在更新现有记录,所以为了更新,我们创建了一个 JSON 文档。若要更新数据,我们单击“更新记录”按钮。所以,当我们单击“提交”按钮时,将调用 updateDoc() 函数。该函数创建一个 XMLHttpRequest 对象。然后,调用 XHR 对象的 open() 方法以使用 HTTP PUT 方法和服务器的 URL "https://jsonplaceholder.typicode.com/todos/21" 初始化请求。然后,调用 setRequestHeader() 方法以将请求的内容类型设置为 JSON。之后,调用 send() 函数以将请求连同 JSON 文档一起发送。当服务器收到该请求时,它使用新数据更新所指定的记录。
如果更新成功,那么将使用“就绪状态 = 4(表示请求已完成)”和“状态 = 200(表示成功响应)”调用回调函数。然后,更新的数据将显示在屏幕上。它还会向控制台输出一条消息,表示数据已成功更新。
此处使用 JSON.stringify() 方法将 JSON 文档转换为字符串。这是必需的,因为 XHR 请求只能发送文本数据。
NOTE − 当你使用 PUT 方法时,有必要像 "https://jsonplaceholder.typicode.com/todos/21" 这样在 URL 中指定记录 ID。在此处,我们更新了一个 ID 为 21 的记录。
AJAX - Send JSON Data
AJAX 是异步 Javascript 和 XML。它是由用于开发动态网页应用的网页技术结合而成,该应用能够在后台发送和检索服务器中的数据,无需重新加载整个页面。
JSON(JavaScript 对象表示法)是一个格式,其中我们可以存储数据并且可以在不同的计算机系统之间传输数据。它易于理解且与语言无关。AJAX 可以用 JSON 或任何明文传输任何类型的数据。因此,在这篇文章中,我们将学习如何使用 AJAX 发送 JSON 数据。
Send JSON Data
要使用 AJAX 发送 JSON 数据,请遵循以下步骤 −
Step 1 − 创建一个新的 XMLHttpRequest 实例。
Step 2 − 设置请求方法,即 open() 方法和 URL。
Step 3 − 设置请求头来指定数据格式。此处将 content-type 头设置为“application/json”,指示即将以 JSON 格式发送数据。
Step 4 − 创建用于处理响应的回调函数。
Step 5 − 编写 JSON 数据。
Step 6 − 使用 JSON.stringify() 方法将 JSON 数据转换为字符串。
Step 7 − 现在使用 send() 方法发送请求,同时将 JSON 数据作为请求正文。
以下是显示下面代码工作原理的流程图 −
Example
<!DOCTYPE html>
<html>
<body>
<script>
function sendDoc() {
// Creating XMLHttpRequest object
var qhttp = new XMLHttpRequest();
// Creating call back function
qhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 201) {
document.getElementById("sample").innerHTML = this.responseText;
console.log("JSON Data Send Successfully")
}
};
// Open the given file
qhttp.open("POST", "https://jsonplaceholder.typicode.com/todos", true);
// Setting HTTP request header
qhttp.setRequestHeader('Content-type', 'application/json')
// Sending the JSON data to the server
qhttp.send(JSON.stringify({
"title": "Mickey",
"userId": 11,
"id": 21,
"body": "Mickey lives in london"
}));
}
</script>
<h2>Sending JSON Data</h2>
<button type="button" onclick="sendDoc()">Uplodaing Data</button>
<div id="sample"></div>
</body>
</html>
Output
在此上面的示例中,我们使用 POST 方法向给定 URL 处的服务器发送以下 JSON 文档 −
{
"title": "Mickey",
"userId": 11,
"id": 21,
"body": "Mickey lives in london"
}
因此,当我们点击“更新数据”按钮时,会调用 sendDoc() 函数。此函数会创建 XMLHttpRequest 对象。然后调用 XHR 对象的 open() 方法,以使用 HTTP POST 方法和服务器的 URL "https://jsonplaceholder.typicode.com/todos" 来初始化请求。之后,调用 setRequestHeader() 方法,将请求的内容类型设置为 JSON。然后调用 send() 函数发送请求以及 JSON 文档。当服务器接收到请求后,它会添加该文档。
如果更新成功,那么回调函数会被调用,并且“准备就绪状态 = 4(表明请求已完成)”和“状态 = 201(表明服务器已成功创建一个新资源)”。然后服务器的响应会用 HTML 文件显示出来,使用 sample 元素的 innerHTML 属性。它还会在控制台中打印一条消息,表示 JSON 数据已成功发送。
此处使用 JSON.stringify() 方法将 JSON 文档转换为字符串。这是必需的,因为 XHR 请求只能发送文本数据。
AJAX - Send Data Objects
在 AJAX 中,我们允许将数据对象作为 HTTP 请求的一部分从客户端发送到 Web 服务器。数据对象是一个包含键值对中的数据的对象。它们通常用 JavaScript 对象表示。所以在 AJAX 中发送数据对象表示我们正在将结构化数据传递给服务器以进一步处理。它可以包含表单输入、用户输入、用户信息或任何其他信息。我们不仅能使用数据对象,还可以使用 AJAX 将文件从系统上传并使用 XMLHttpRequest 发送。
以下为数据对象格式−
var myDataObject = {
"name": "Pinky",
"City": "Pune",
"Age": 23
}
现在,若要使用 XMLHttpRequest 发送此数据对象,我们需要使用 stringify() 方法将该对象转换为 JSON 字符串,因为大多数框架都非常轻松、无需任何额外的努力就能支持 JSON 格式。stringify() 方法是 JavaScript 内置函数,用于将对象或值转换为 JSON 字符串。
Example
在以下程序中,我们将使用 XMLHttpRequest 发送数据对象。为此,我们将创建一个 XMLHttpRequest 对象,然后创建一个包含我们想要发送的数据的数据对象。然后,我们使用 stringify() 函数将数据对象转换为 JSON 字符串,并将头部设置为 "application/json" 以便告诉服务器该请求包含 JSON 数据。然后,我们使用 send() 函数发送数据对象,并且响应由回调函数进行处理。
<!DOCTYPE html>
<html>
<body>
<script>
function sendDataObject() {
// Creating XMLHttpRequest object
var qhttp = new XMLHttpRequest();
// Creating data object
var myDataObject = {
"name": "Monika",
"City": "Delhi",
"Age": 32,
"Contact Number": 33333333
}
// Creating call back function
qhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 201) {
document.getElementById("sample").innerHTML = this.responseText;
console.log("Data object Send Successfully")
}
};
// Open the given file
qhttp.open("POST",
"https://jsonplaceholder.typicode.com/todos", true);
// Setting HTTP request header
qhttp.setRequestHeader('Content-type', 'application/json')
// Converting data object to a string
var myData = JSON.stringify(myDataObject)
// Sending the data object to the server
qhttp.send(myData)
}
</script>
<h2>Sending Data object</h2>
<button type="button" onclick="sendDataObject()">Submit</button>
<div id="sample"></div>
</body>
</html>
AJAX - Monitoring Progress
AJAX 提供了一个名为监视进度(Monitoring Progress)的特殊特性。通过此功能,我们可以追踪 AJAX 从 Web 浏览器到 Web 服务器做出的异步请求的进度。或者,我们可以说,使用进度监视器,还可以监视上传或从服务器下载的数据量。借助监视进度,我们可以向用户发送包含以下要点反馈:
Data Transfer Progress - 我们可以监视从服务器传输到客户端的数据的进度。或者,我们还可以追踪传输或接收了多少数据,以与给定文件的大小进行比较。
Request Status - Wan 还可以监视我们做出的请求的一般状态(例如,请求是否仍在进行中、已完成或待处理)。它可以帮助程序员向用户提供当前请求的适当反馈。
Error Handling - 除了追踪当前状态之外,在请求数据时处理任何错误也很重要,例如服务器端错误、网络问题等。因此,通过错误处理,我们可以轻松地向用户发送通知,以便他/她可以对发生的错误采取适当的操作。
How to Monitor Progress
若要监视 AJAX 请求的进度,我们可以使用以下方法:
Using onprogress event - 若要监视请求的进度,我们可以定义一个 “onprogress” 事件,该事件会在数据传输处理期间定期触发。它通常用于监视文件下载或大型数据/文件传输的进度。它监视的信息进度,例如加载了多少数据、传输数据的总大小等。
Example
在以下程序中,我们将借助 onprogress 事件监视请求的当前状态。此处,我们创建一个名为 displayStatus() 的 Javascript 函数,该函数显示已传输了多少数据的状态。此函数发出一个 AJAX 请求以将数据发送到指定的 URL。因此,它使用 XMLHttpRequest 对象创建请求,然后定义一个回调函数来处理服务器提供的响应。在回调函数内。onprogress 事件检查传输数据的当前进度。在 onprogress 事件处理程序内,我们可以检查进度数据是否可计算,以避免除以零错误。如果它可计算,那么我们可以计算传输到服务器的数据百分比。
<script>
function displayStatus() {
// Creating XMLHttpRequest object
var myObj = new XMLHttpRequest();
// Creating call back function
// Here onprogress return the percentage of transferred data
myObj.onprogress = function(myEvent) {
if (myEvent.lengthComputable){
var dataTarnsferPercentage = (myEvent.loaded/myEvent.total)*100;
console.log("Current progress of the data transfer:", dataTarnsferPercentage);
}
};
// Open the given file
myObj.open("GET", "https://jsonplaceholder.typicode.com/todos", true);
// Sending the request to the server
myObj.send();
}
</script>
Using onreadystatechange event − 我们可以通过生成一个 onreadystatechnage 事件来监控请求的进展情况。当 XMLHttpRequest 的 readyState 属性发生改变时,该事件就会触发。readyState 属性返回请求的当前状态。
Example
在下面的程序中,我们将借助 onreadystatechange 事件来监控请求的当前状态。这里我们创建了一个名为 displayStatus() 的 JavaScript 函数,该函数显示请求的当前状态。该函数执行一个 AJAX 请求,从给定的 URL 检索数据。因此,它使用一个 XMLHttpRequest 对象来创建请求,然后定义一个回调函数来处理服务器提供的响应。在回调函数内。onreadystatechange 事件利用 readyState 属性检查请求的当前状态。如果 readyState 是 XMLHttpRequest.DONE,表示请求已完成,并打印“请求已完成”。否则打印“请求正在进行”。
<script>
function displayStatus() {
// Creating XMLHttpRequest object
var myObj = new XMLHttpRequest();
// Creating call back function
// Here onreadystatechange return the current state of the resuest
myObj.onreadystatechange = function() {
if (this.readyState == XMLHttpRequest.DONE){
console.log("Request is completed")
}else{
console.log("Request is in-progress")
}
};
// Open the given file
myObj.open("GET", "https://jsonplaceholder.typicode.com/todos", true);
// Sending the request to the server
myObj.send();
}
</script>
AJAX - Status Codes
在 AJAX 中,XMLHttpRequest 支持各种属性和方法来执行不同类型的操作。在这些属性和方法中,状态属性/特性是一个状态代码,它指定了 XMLHttpRequest 对象发送的数据请求的整体状态。或者我们可以说状态代码是一个三位数字,它表示 XMLHttpRequest 对象发送的请求的结果,比如请求是否成功、遇到错误或被重定向等。
因此,状态属性的语法如下−
Format
if(XMLHttpRequestObjectName.status == 200){
// Body
}
在这里,我们可以使用 XMLHttpRequest 对象访问状态属性。如果状态代码等于 200,则会执行 body 中的代码。
Status Codes
HTTP 状态返回的状态码如下:
Successful
Status |
Message |
Description |
200 |
OK |
如果请求可以。 |
201 |
Created |
当请求完成并创建了一个新资源。 |
202 |
Accepted |
当请求被服务器接受。 |
204 |
No Content |
当响应主体中没有数据。 |
205 |
Reset Content |
对于其他输入,浏览器会清除用于事务的表单。 |
206 |
Partial Content |
当服务器返回指定大小的部分数据。 |
Redirection
Status |
Message |
Description |
300 |
Multiple Choices |
它用于表征链接列表。因此,用户可以选择任何一个链接并前往该位置。它只允许五个位置。 |
301 |
Moved Permanently |
当请求的页面移动到新 URL。 |
302 |
Found |
当请求的页面在不同的 URL 中找到。 |
304 |
Not modified |
URL is not modified. |
Client Error
Status |
Message |
Description |
400 |
Bad Request |
服务器无法满足请求,因为请求格式错误或语法无效。 |
401 |
Unauthorised |
请求需要身份验证,并且用户未提供有效凭证。 |
403 |
Forbidden |
服务器了解该请求,但无法完成它。 |
404 |
Not Found |
找不到请求的页面。 |
405 |
Method Not Allowed |
通过该请求进行请求的方法不受该页面支持。 |
406 |
Not Acceptable |
客户无法接受服务器生成的响应。 |
408 |
Request Timeout |
Server timeout |
409 |
Conflict |
请求由于请求中的冲突而未完成。 |
410 |
Gone |
请求的页面不可用。 |
417 |
Exception Failed |
服务器不匹配 Expect 请求头字段的要求。 |
Server Error
Status |
Message |
Description |
500 |
Internal Server Error |
当服务器在处理请求时遇到错误 |
501 |
Not Implemented |
当服务器无法识别请求方法或无法满足请求 |
502 |
Bad Gateway |
当服务器充当网关并从另一台服务器(上游)中恢复无效响应 |
503 |
Service Unavailable |
当服务器不可用或宕机 |
504 |
Gateway Timeout |
当服务器作为网关且未及时从另一台服务器(上游)收到响应时。 |
505 |
HTTP Version Not Supported |
当服务器不支持 HTTP 协议版本时。 |
511 |
Network Authentication Required |
当客户端需要验证以获取对网络的访问权限时。 |
Flow Chart
在以下代码中,我们从服务器中检索数据。因此,我们创建一个名为 showDoc() 的函数。现在,我们通过单击“单击此处”按钮来调用此函数。此函数将使用 XMLHttpRequest() 构造函数创建一个新的 XHR 对象。然后它创建一个回调函数,它将处理请求。然后它调用 XHR 对象的 open() 函数,使用 HTTP GET 方法和服务器的 URL 初始化请求。最后,它调用 send() 函数向服务器发送请求。
因此,当服务器响应请求时,“onreadystatechange”属性使用 XMLHttpRequest 对象的当前状态调用回调函数。如果状态为 200,则表示请求成功,因此它在屏幕上显示结果并在控制台日志中写入消息。如果状态为 404,则表示服务器遇到错误。因此,我们在控制台日志中收到一条错误消息。
Example
<!DOCTYPE html>
<html>
<body>
<script>
function ShowDoc() {
// Creating XMLHttpRequest object
var myhttp = new XMLHttpRequest();
// Creating call back function
myhttp.onreadystatechange = function() {
// Checking the status of the response
// This will proceed when the response is successful
if (this.status == 200){
console.log("Found the requested data")
document.getElementById("example").innerHTML = this.responseText;
}
// This will proceed when the error is found
else if(this.status == 404){
console.log("Found error");
}
};
// Open the given file
myhttp.open("GET", "https://jsonplaceholder.typicode.com/todos/3", true);
// Sending the request to the server
myhttp.send();
}
</script>
<p>Please click on the button to fetch data</p>
<button type="button" onclick="ShowDoc()">Click Here</button>
<div id="example"></div>
</body>
</html>
AJAX - Applications
AJAX 是一种常用的 Web 技术,可异步地向 Web 服务器发送和接收数据,而无需重新加载网页的所有组件。它易于理解和使用,因为它不使用任何新技术,而是现有 Web 技术(如 JavaScript、XML、HTML 等)的组合。它使 Web 应用程序更具响应性和交互性,以便它们可以在不刷新整页的情况下实时获取和显示数据。由于其强大的功能,几乎所有 Web 应用程序创建者(包括小型或大型公司)都使用它。
几乎所有当前互联网上的应用程序都普遍使用 AJAX。一些流行的应用程序有:
Google Maps - 它是一个 AJAX 应用程序的很好的例子。它使用 AJAX 动态更新地图,并仅显示请求的数据,而无需重新加载整个页面。
Facebook - 它也是一个 AJAX 应用程序的好例子。它使用 AJAX 更新提要、通知、新闻和其他功能。Ajax 还用于根据用户的操作更新网页的 Facebook 内容。
Gmail - Gmail 也使用 AJAX 为用户提供无缝且交互式环境。在 AJAX 的帮助下,Gmail 可以更新收件箱、删除电子邮件或将电子邮件标记为已读,而无需重新加载页面。
Twitter - Twitter 也是 AJAX 应用程序的一个很好的例子。使用 AJAX 为用户提供实时环境。每当发布新推文时,它都会添加到时间线中,而无需刷新整个页面。通知也是如此。
Online shopping websites - 在线购物网站还使用 AJAX 来显示产品详细信息及其实时价格,而无需用户导航到新网页。
Google - Google 还将其自动完成功能用于 AJAX。当用户在 Google 搜索栏中输入内容时,自动完成功能就会显示在图片中,然后此功能可在下拉列表中提供实时建议,而无需重新加载原始网页。此功能也以各种形式使用。
Chats and instant messages - 如今,大多数网站使用客户支持聊天设施,通过该设施可以在不重新加载整个网页的情况下与其客户进行通信。AJAX 也实现了此功能。
Form submission and validations - 各种网站将 AJAX 用于表单的提交和验证。它在表单的某些字段中提供自动填充功能,并且可以为指定字段的可能条目提供建议(如自动完成功能)。AJAX 也用于验证用户的凭据。
Voting and rating systems - 各种网站使用评级和投票系统,允许用户根据投票和评级自定义数据。此外,用户可以投票或对给定网站上的内容进行评级,然后该网站会相应地更新其内容。此类网站使用 AJAX 来管理用户投票和评级。
AJAX - Browser Compatibility
AJAX 创建动态网页,在其中用户和服务器之间的通信在后台进行,而无需加载整个页面。因此,了解浏览器的兼容性非常重要,因为不同的浏览器可以以不同的方式实现 XMLHttpRequest 对象及其相关属性和方法。
以下是有助于检查浏览器兼容性的要点 −
Support XMLHttpRequest’s object − 浏览器必须支持 XMLHttpRequest 对象。一些旧浏览器(如 Internet Explorer 6 或更早版本)不支持 XMLHttpRequest 对象。要使它们与其他浏览器兼容,你需要使用回退方法,使用 iframe 或表单元素来运行所有 AJAX 功能。
Cross-origin request − 某些浏览器不支持使用 XMLHttpRequest 进行的跨域请求。因此,为了防止这些漏洞,我们使用 JSONP(带填充的 JSON)、CORS(跨域资源共享)或代理服务器进行跨域请求。
Response Type − 不同的浏览器可能支持不同的响应类型,例如,文本、JSON、XML、二进制数据等,适用于 XMLHttpRequest。所以如果你想让你的应用程序支持广泛的网络浏览器,你需要找到受支持的响应类型并明智地处理它。
Error handling − 不同的浏览器以不同的方式处理 XMLHttpRequest 错误,因此你需要检查你的错误处理代码以确保它适用于所有浏览器。
Event Handling − 不同的浏览器可能有自己的方式处理 XMLHttpRequest 的事件,如 onload 等。因此,你需要测试并调整代码以确保它适用于所有浏览器。
虽然大多数现代浏览器,如 Google Chrome、Mozilla Firefox、Microsoft Edge、Safari 和 Opera,完全支持 AJAX,但一些较旧的浏览器,如 Internet Explorer 6 和 7,对 AJAX 的支持有限。因此,永远不要忘记浏览器的兼容性,因为它会影响 AJAX Web 应用程序的工作。
AJAX - Examples
以下是一些使用 AJAX 的著名 Web 应用程序列表。
Difference between AJAX and Conventional CGI Program
逐一尝试这两个示例,您会感受到不同之处。在尝试 AJAX 示例时,没有不连续性,您会很快得到响应,但是当您尝试标准 GCI 示例时,您将不得不等待响应,您的页面也会刷新。
Standard Example
NOTE − 我们提供了一个更复杂的示例,请参阅 AJAX Database 。
AJAX - Browser Support
并不是所有可用的浏览器都支持 AJAX。以下是支持 AJAX 的主要浏览器的列表。
-
Mozilla Firefox 1.0 及更高版本。
-
Netscape 7.1 及更高版本。
-
Apple Safari 1.2 及更高版本。
-
Microsoft Internet Explorer 5 及更高版本。
-
Konqueror.
-
Opera 7.6 and above.
当你编写下一个应用程序时,请考虑不支持 AJAX 的浏览器。
NOTE − 当我们说某个浏览器不支持 AJAX 时,仅仅意味着浏览器不支持创建 JavaScript 对象 − XMLHttpRequest 对象。
Writing Browser Specific Code
让你的源代码与浏览器兼容的最简单方法是在你的 JavaScript 中使用 try…catch 块。
Example
<html>
<body>
<script language = "javascript" type = "text/javascript">
<!--
//Browser Support Code
function ajaxFunction() {
var ajaxRequest; // The variable that makes Ajax possible!
try {
// Opera 8.0+, Firefox, Safari
ajaxRequest = new XMLHttpRequest();
} catch (e) {
// Internet Explorer Browsers
try {
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
// Something went wrong
alert("Your browser broke!");
return false;
}
}
}
}
//-->
</script>
<form name = 'myForm'>
Name: <input type = 'text' name = 'username' /> <br />
Time: <input type = 'text' name = 'time' />
</form>
</body>
</html>
Output
在上面的 JavaScript 代码中,我们尝试三次创建 XMLHttpRequest 对象。我们的第一次尝试 −
-
ajaxRequest = new XMLHttpRequest();
这是适用于 Opera 8.0+、Firefox 和 Safari 浏览器的。如果失败,我们会尝试再两次,使用适用于 Internet Explorer 浏览器的 − 来创建正确对象。
-
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
-
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
如果这也不行,那我们可能使用的是不支持 XMLHttpRequest 的非常过时的浏览器,这也意味着它不支持 AJAX。
不过,最有可能的是,我们的变量 ajaxRequest 现在将被设置为浏览器使用的任何 XMLHttpRequest 标准,并且我们可以开始向服务器发送数据。逐步 AJAX 工作流程将在下一章中进行说明。
AJAX - XMLHttpRequest
在 AJAX 中,XMLHttpRequest 扮演着非常重要的角色。XMLHttpRequest 用于在后台与 Web 服务器交换数据,而用户/客户端在前台工作,然后使用收到的数据更新网页部分,而无需重新加载整个页面。
我们还可以说,XMLHttpRequest (XHR) 可以由各种 Web 浏览器脚本语言(如 JavaScript、JScript、VBScript 等)使用,通过 HTTP 与 Web 服务器交换 XML 数据。除了 XML 外,XMLHttpRequest 还可以获取各种格式的数据,如 JSON 等。它会在客户端和服务器端之间创建异步连接。
Syntax
variableName = new XMLHttpRequest()
当使用新关键字和 XMLHttpRequest() 构造函数时,我们可以创建一个新的 XMLHttpRequest 对象。必须先创建此对象,然后才能调用 open() 函数对其进行初始化,然后再调用 send() 函数将请求发送到 Web 服务器。
XMLHttpRequest Object Methods
XMLHttpRequest 对象具有以下方法:
Sr.No. |
Method & Description |
1 |
new XMLHttpRequest() 用于创建 XMLHttpRequest() 对象 |
2 |
abort() 用于取消当前请求。 |
3 |
getAllResponseHeaders() 用于获取标头信息 |
4 |
getResponseHeader() 用于获取特定标头信息 |
5 |
open(method, url, async, user, psw) open(method, url, async, user, psw) 用于初始化请求参数,其中,method:请求类型 GET 或 POST 或其他类型 url:文件位置 async:对于异步设置为 true,或对于同步设置为 false user:对于可选的用户名 psw:对于可选的密码 |
6 |
send() 用于向 Web 服务器发送请求。它通常用于 GET 请求。 |
7 |
send(string) 用于向服务器发送请求。它通常用于 POST 请求。 |
8 |
setRequestHeader() 用于向头部中添加键/值对。 |
XMLHttpRequest Object Properties
XMLHttpRequest 对象具有以下属性:
Sr.No. |
Property & Description |
1 |
onreadystatechange 设置处理请求状态更改的回调函数。 |
2 |
readyState 用于保存 XMLHttpRequest 的状态。它具有以下值:- 它表示未初始化请求- 它表示已建立服务器连接- 它表示已收到请求- 它表示正在处理请求- 它表示请求已完成且响应已准备就绪 |
3 |
responseText 用于将响应数据作为字符串返回。 |
4 |
responseXML 用于将响应数据作为 XML 数据返回 |
5 |
Status 用于返回请求的状态号。例如:- 200:确定- 403:禁止- 404:未找到 |
6 |
StatusText 它用于返回状态文本。例如,OK、未找到等。 |
Usage of XMLHttpRequest
在了解了 XMLHttpRequest 的基本语法、方法和属性之后,现在我们学习如何实际使用 XMLHttpRequest。因此,要在您的程序中使用 XMLHttpRequest,首先我们需要遵循以下主要步骤 −
Step 1 − 创建 XMLHttpRequest 对象。
var variableName = new XMLHttpRequest()
Step 2 − 在创建 XMLHttpRequest 对象后,我们现在必须定义一个回调函数,该函数将在从 Web 服务器获取响应后触发。
XMLHttpRequestObjectName.onreadystatechange = function(){
// Callback function body
}
XMLHttpRequestObjectName.open(method, url, async)
XMLHttpRequestObjectName.send()
Step 3 − 现在我们使用 open() 和 send() 函数向 Web 服务器发送请求。
现在让我们借助以下示例来了解 XMLHttpRequest 的工作方式:
Example
在下面的示例中,我们将从服务器获取数据。要从服务器获取数据,我们将单击“单击我”按钮。因此,当我们单击“单击我”按钮时,将调用 displayDoc() 函数。在 displayDoc() 函数中,我们创建一个 XMLHttpRequest 对象。然后,我们创建一个回调函数来处理服务器响应。然后,我们调用 XHR 对象的 open() 方法,使用 HTTP GET 方法和服务器 URL 来初始化请求,网址为 "https://jsonplaceholder.typicode.com/todos" 。然后我们调用 send() 函数来发送请求。
因此,当服务器响应请求时,“onreadystatechange”属性会使用 XMLHttpRequest 对象的当前状态调用回调函数。如果“就绪状态”属性设置为 4(意味着请求已完成),并且“状态”属性设置为 200(意味着响应成功),则响应数据将从“responseText”属性中提取,并使用“innerHTML”属性显示 HTML 文档示例元素的。
如果在请求过程中发现错误,则回调函数中存在的 else 语句将执行。因此,这就是我们从服务器获取数据的方式。
<!DOCTYPE html>
<html>
<body>
<script>
function displayDoc() {
// Creating XMLHttpRequest object
var myObj = new XMLHttpRequest();
// Creating a callback function
myObj.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("sample").innerHTML = this.responseText;
} else {
console.log("Error Found")
}
};
// Open the given file
myObj.open("GET", "https://jsonplaceholder.typicode.com/todos", true);
// Sending the request to the server
myObj.send();
}
</script>
<div id="sample">
<h2>Getting Data</h2>
<p>Please click on the button to fetch data</p>
<button type="button" onclick="displayDoc()">Click Me</button>
</div>
</body>
</html>
AJAX - Database Operations
为了清楚地说明使用 AJAX 从数据库中访问信息有多么容易,我们将即时构建 MySQL 查询,并将结果显示在 “ajax.html” 上。但在此之前,让我们做一些基础工作。使用以下命令创建一个表。
NOTE − 我们假设您有足够的权限执行以下 MySQL 操作。
CREATE TABLE 'ajax_example' (
'name' varchar(50) NOT NULL,
'age' int(11) NOT NULL,
'sex' varchar(1) NOT NULL,
'wpm' int(11) NOT NULL,
PRIMARY KEY ('name')
)
现在使用以下 SQL 语句将以下数据转储到此表中 −
INSERT INTO 'ajax_example' VALUES ('Jerry', 120, 'm', 20);
INSERT INTO 'ajax_example' VALUES ('Regis', 75, 'm', 44);
INSERT INTO 'ajax_example' VALUES ('Frank', 45, 'm', 87);
INSERT INTO 'ajax_example' VALUES ('Jill', 22, 'f', 72);
INSERT INTO 'ajax_example' VALUES ('Tracy', 27, 'f', 0);
INSERT INTO 'ajax_example' VALUES ('Julie', 35, 'f', 90);
Client Side HTML File
现在,我们提供客户端 HTML 文件 ajax.html,其中将具有以下代码 −
Example
<html>
<body>
<script language = "javascript" type = "text/javascript">
<!--
//Browser Support Code
function ajaxFunction() {
var ajaxRequest; // The variable that makes Ajax possible!
try {
// Opera 8.0+, Firefox, Safari
ajaxRequest = new XMLHttpRequest();
} catch (e) {
// Internet Explorer Browsers
try {
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
// Something went wrong
alert("Your browser broke!");
return false;
}
}
}
// Create a function that will receive data
// sent from the server and will update
// div section in the same page.
ajaxRequest.onreadystatechange = function() {
if(ajaxRequest.readyState == 4) {
var ajaxDisplay = document.getElementById('ajaxDiv');
ajaxDisplay.innerHTML = ajaxRequest.responseText;
}
}
// Now get the value from user and pass it to
// server script.
var age = document.getElementById('age').value;
var wpm = document.getElementById('wpm').value;
var sex = document.getElementById('sex').value;
var queryString = "?age = " + age ;
queryString += "&wpm = " + wpm + "&sex = " + sex;
ajaxRequest.open("GET", "ajax-example.php" + queryString, true);
ajaxRequest.send(null);
}
//-->
</script>
<form name = 'myForm'>
Max Age: <input type = 'text' id = 'age' /> <br />
Max WPM: <input type = 'text' id = 'wpm' /> <br />
Sex:
<select id = 'sex'>
<option value = "m">m</option>
<option value = "f">f</option>
</select>
<input type = 'button' onclick = 'ajaxFunction()' value = 'Query MySQL'/>
</form>
<div id = 'ajaxDiv'>Your result will display here</div>
</body>
</html>
NOTE − 查询中传递变量的方法根据 HTTP 标准,并带有 formA。
URL?variable1 = value1;&variable2 = value2;
以上代码将向您提供以下屏幕 −
Server Side PHP File
您的客户端脚本已准备就绪。现在,我们必须编写我们的服务器端脚本,它将从数据库中提取 age、wpm 和 sex,然后将其发送回客户端。将以下代码放入 "ajax-example.php" 文件中。
<?php
$dbhost = "localhost";
$dbuser = "dbusername";
$dbpass = "dbpassword";
$dbname = "dbname";
//Connect to MySQL Server
mysql_connect($dbhost, $dbuser, $dbpass);
//Select Database
mysql_select_db($dbname) or die(mysql_error());
// Retrieve data from Query String
$age = $_GET['age'];
$sex = $_GET['sex'];
$wpm = $_GET['wpm'];
// Escape User Input to help prevent SQL Injection
$age = mysql_real_escape_string($age);
$sex = mysql_real_escape_string($sex);
$wpm = mysql_real_escape_string($wpm);
//build query
$query = "SELECT * FROM ajax_example WHERE sex = '$sex'";
if(is_numeric($age))
$query .= " AND age <= $age";
if(is_numeric($wpm))
$query .= " AND wpm <= $wpm";
//Execute query
$qry_result = mysql_query($query) or die(mysql_error());
//Build Result String
$display_string = "<table>";
$display_string .= "<tr>";
$display_string .= "<th>Name</th>";
$display_string .= "<th>Age</th>";
$display_string .= "<th>Sex</th>";
$display_string .= "<th>WPM</th>";
$display_string .= "</tr>";
// Insert a new row in the table for each person returned
while($row = mysql_fetch_array($qry_result)) {
$display_string .= "<tr>";
$display_string .= "<td>$row[name]</td>";
$display_string .= "<td>$row[age]</td>";
$display_string .= "<td>$row[sex]</td>";
$display_string .= "<td>$row[wpm]</td>";
$display_string .= "</tr>";
}
echo "Query: " . $query . "<br />";
$display_string .= "</table>";
echo $display_string;
?>
现在尝试在 Max Age 或任何其他框中输入有效值 (例如 120),然后单击 Query MySQL 按钮。
在您进行输入后,您的结果将在此部分显示。
如果您已成功完成此课程,那么您就会知道如何同时使用 MySQL、PHP、HTML 和 Javascript 来编写 AJAX 应用程序。
AJAX - Security
AJAX 是最常用的 Web 技术,用于在不干扰客户端应用程序其他组件的功能的情况下异步地向 Web 服务器发送和接收数据。尽管 AJAX 本身不提供任何安全漏洞,但我们在实现 AJAX 时仍必须保持一些安全措施。安全措施有 −
Cross-Site Scripting(XSS) − AJAX 应用程序应该容易受到 XSS 攻击。如果未实施适当的输入验证和输出编码,那么黑客可以轻松地在 AJAX 响应中注入恶意脚本。这些恶意脚本用于窃取系统中的敏感数据或可以篡改内容。因此,始终创建一种 AJAX 应用程序,该应用程序可以通过在网页上显示数据之前使用适当的验证和消毒来防止此攻击。
Cross-Site Request Forgery(CSRF) − 在此攻击中,攻击者通过借助身份验证会话来欺骗浏览器执行不需要的操作。它可以利用 AJAX 请求并可以执行未经授权的操作。因此,为了防止此攻击,我们必须实施 CSRF 保护技术,例如生成和验证随机令牌,或者可以使用同源策略。
Insecure Direct Object References(IDOR) − 该请求通常借助唯一标识符从服务器访问指定资源。但是,如果攻击者获得了此标识符,则可以轻松地操纵或访问未经授权的资源。因此,为了防止这种情况,避免泄露敏感信息。此外,在服务器端检查开发人员对指定资源的用户授权。
Content Security Policies(CSP) − 这是帮助用户/开发人员保护自身免受恶意活动或未经授权访问的政策。它为安全脚本和其他资源提供了一个允许的来源。
Server-Side validation − 服务器端验证非常重要,因为它确保提交的数据符合指定的条件且对进一步处理是安全的。我们无法绕过或操纵服务器端验证,但我们可以绕过客户端验证。
Secure Session Management − AJAX应用程序应妥善维护用户会话和会话令牌,以防止会话受到攻击。始终检查会话令牌是否生成了正确并安全地传输了,并在无效或会话期满时注销。
Input Validation and Sanitization − 服务器应对从客户端接收到的数据进行校验和净化操作,以防止攻击。
Regular Update and Security − 众所周知,AJAX 使用外部库或框架。因此,让它们保持最新至关重要。这有利于避免各种漏洞,并提升应用程序的安全性。
AJAX - Issues
世界上每项技术都有其光明面和黑暗面,类似地,AJAX 是一项用于开发动态和交互式 Web 应用程序的强大技术,但也存在一些挑战和问题。因此,与 AJAX 相关的常见问题有 −
Cross-Domain Requests − 在 AJAX 中,请求通常符合同源策略。此策略出于安全目的会将请求限制为同域,这意味着,如果您尝试在不同的域中进行 AJAX 请求,将获得一个 CORS 错误。因此,为了解决此错误,您需要重新配置系统,并借助 JSONP 或代理服务器允许跨域请求。
Security Vulnerability − 在 AJAX 中,请求可能会受到 XSS(跨站点脚本)或 CSRF(跨站点请求伪造)的攻击。因此,为了避免此类漏洞,我们必须使用输入验证、输出编码和 CSRF 保护令牌。
Browser Support − 由于某些浏览器的版本不支持 AJAX 功能,因此导致浏览器兼容性问题。因此,在使用 AJAX 时,请检查浏览器是否能进行或支持 AJAX 请求。
Performance Impact − 如果我们未正确优化 AJAX 请求,则它将影响性能。如果我们传输过量数据、不必要的请求、频繁的请求或低效的服务器端处理,这些活动将导致页面加载时间变慢并会增加服务器负载。因此,务必提出恰当而优化的请求。
Search Engine Optimization(SEO) − 由于旧的网络爬虫不会执行 JavaScript,搜索引擎通常在索引由 AJAX 驱动的内容时面临挑战。这将影响搜索引擎中网页的排名和发现。
Testing and Debugging − 由于请求的异步行为,调试 AJAX 代码十分困难。因此,为了解决此问题,我们必须使用优秀的调试工具,这些工具可以识别问题并正确解决它们。
JavaScript Dependency − AJAX 通常依赖于 JavaScript。因此,如果在 Web 浏览器中禁用了 JavaScript,我们将无法使用 AJAX 功能。因此,为了获得更佳体验,请务必在 Web 浏览器中启用 JavaScript。
Code complexity − AJAX 代码很复杂,尤其是在处理异步流和管理响应时。因此,为了解决此问题,务必创建组织良好、易于维护且清晰的代码,其中各个问题在单独的代码中进行维护,以便开发人员能够轻松理解。
Dependency Management − 我们知道 AJAX 是使用各种 Web 技术实现的,因此必须依赖于外部库或框架。因此,管理依赖项和及时更新它们对于 AJAX 来说是一项最大的挑战,尤其是在我们使用多个组件或插件时。
Fetch API - Basics
Fetch 是一种基于承诺的 API,它提供了一个 JavaScript 接口来访问或以异步方式操作请求和响应。与 XMLHttpRequest 相比,它功能更强大,使用 Fetch API,我们可以向服务器发送数据,也可以从服务器异步请求数据。它还使用请求和响应对象以及 CORS 和 HTTP 起源头部概念。
以下是 Fetch API 的关键组件 −
-
fetch() function − 要获取资源或创建请求,Fetch API 使用名为 fetch() 的全局方法。它返回一个承诺,该承诺进一步解析为 Response 对象。
-
Request and Response Object − Request 对象用于表示使用 URL、头等全部信息发送的请求。而 Response 对象用于表示服务器返回的响应,其中包括状态代码、正文和响应头。
-
Promises − Fetch API 基于承诺,因为它们处理操作并异步管理响应流。使用承诺,我们可以创建一系列操作,并可以使用 .then() 和 .catch() 函数来处理成功和错误。
-
Customization − 使用 Fetch API,我们可以通过指定方法、向请求添加正文、设置头、处理不同格式的数据等来定制请求。
-
CROS − Fetch API 为 CROS(跨域资源共享)提供了良好的支持,这允许用户向不同域发出请求。
Working of Fetch API
Fetch API 用于从 Web 浏览器的 JavaScript 代码创建 HTTP 请求。因此,使用以下步骤,我们将了解 Fetch API 从发送请求到接受响应的工作原理 -
下面是上面流程图的分步说明 -
Step 1 − 请求初始化:在客户端,JavaScript 程序使用 fetch() 函数创建请求对象。在此 fetch() 函数中,我们将传递要从中获取资源的资源 URL 以及其他可选控件,如头、方法、正文等。
Step 2 − 发送请求:在初始化请求之后,Fetch API 会使用给定的 URL 将请求发送到服务器。如果该请求是 GET 请求,则浏览器会将请求直接发送到服务器。如果该请求不是 GET 请求,则浏览器会发送一个预检 OPTIONS 请求,以检查服务器是否允许该请求。
Step 3 − 服务器处理:接收到请求后,服务器会处理该请求。它可以对该请求执行各种操作,如处理请求、检索数据等。
Step 4 − 生成响应:现在,服务器根据给定的请求生成响应。服务器响应通常包含一个状态代码(例如 200 表示成功,404 表示找不到请求等)、响应头和可选的正文。
Step 5 − 接收响应:Web 浏览器从服务器接收到响应。现在,Fetch API 使用承诺来解析服务器发送的响应对象。
Step 6 − 处理响应:Fetch API 使用基于承诺的语法来处理服务器返回的响应。使用它,我们可以访问响应状态、正文和头,并且可以在接收的数据上执行操作。
Step 7 − 解析响应:如果服务器响应包含文本数据,则 JavaScript 程序使用内置方法(如 .json()、.text()、.blob() 等)从响应中解析和提取数据。
Step 8 − 错误处理:如果服务器返回错误,则错误将由 catch() 函数处理。
这些是理解获取 API 工作流程的基本步骤。这些步骤可以根据实际使用情况的复杂性而有所不同。另外,众所周知,Fetch API 是异步的,因此它不会在等待服务器响应时阻塞其他 JavaScript 代码的执行。
Advantages
下面是获取 API 的优点 -
-
Easy to use − 获取 API 提供简单明了的语法来创建异步请求。
-
Promise − 获取 API 使用承诺,因此它可以轻松处理异步操作。承诺提供了一种精确的方法来轻松处理响应和错误。
-
Modern and browser support − 获取 API 是现代网络标准,它内置在 Web 浏览器中,因此几乎所有现代 Web 浏览器和平台都支持它。与 XMLHttpRequest 相比,这使得获取 API 更具一致性和可预测性。
-
Streaming and progressive loading − 获取 API 支持流式响应,这意味着在完全加载响应之前我们可以开始处理它。对于大文件,这通常很有用。
-
In-built JSON support − 获取 API 非常高效地支持 JSON 数据。它可以解析 JSON 响应,并自动将其转换为 JavaScript 对象。
-
Integrate with other APIs − 由于 Fetch API 的行为,它可以轻松地与其他 API 集成,比如 Service Worker API、Cache API 等。
-
More Controls − 使用获取 API,我们可以使用标头、方法、正文等附加参数轻松地自定义请求。
Disadvantages
以下是不利的一面获取 API −
-
Limited web browser support − 几乎所有现代 Web 浏览器都支持获取 API,但较旧的 Web 浏览器不支持它。如果你正在使用较旧的 Web 浏览器,那么你将不得不使用旧方法,比如 XMLHttpRequest 等。
-
Request Cancellation − 获取 API 没有提供任何内置的方法来取消已启动的请求。
-
Timeouts − 获取 API 没有提供任何指定或内置的方法来让请求超时。如果你想强制执行请求的超时,那么你必须手动完成。
-
Error Handling − 获取 API 提供了有限的错误处理方法。它将 2xx 以外的任何 HTTP 状态码都视为错误。这种行为通常适用于某些特定情况,但不适用于所有情况。
-
Progress event for file load − 获取 API 没有为文件上传提供任何内置事件。如果你想监控文件上传的进度,那么你需要额外的库。
-
Cross-origin Limitation − 正如我们所知,获取 API 遵守浏览器的同源策略,因此由于这个跨域请求在服务器端所需的额外 CORS 标头或者受 CORS 预检检查的约束,从而给开发增加了额外的复杂性。
Fetch API Vs XMLHttpRequest
XMLHttpRequest 对象用于与服务器进行异步通信,这意味着可以在后台与服务器交换数据而无需刷新整个页面。XMLHttpRequest 是最常用的技术,这就是为什么它被大多数主流浏览器(如 Google Chrome、Safari、Mozilla Firefox 或 Opera)使用。它还支持纯文本、JSON 数据以及更多数据格式。它非常容易使用,并提供各种方法和属性来执行操作。我们可以使用 XMLHttpRequest() 构造函数创建一个 XMLHttpRequest 对象。
Syntax
variableName = new XMLHttpRequest()
其中,使用 XMLHttpRequest() 构造函数以及一个 new 关键字,我们能够创建一个新的 XMLHttpRequest 对象。必须在调用 send() 函数以向 Web 服务器发送请求之前创建此对象并调用 open() 函数对此对象进行初始化。
Fetch API 提供了一个用于从服务器获取/检索资源的界面。它是 XMLHttpRequest 的一种现代替代方案。它支持请求和响应的通用定义,因此我们可以在需要的情况下将来访问它们以用于缓存 API、服务工作、处理或修改请求和响应等。它非常容易、简单和一致。或者我们可以说它为创建 HTTP 请求和处理响应提供了一种与 XMLHttpRequest 相比更加现代和灵活的方法。它基于 Promise API,该 API 提供了清晰的语法和更好的错误处理。
Syntax
fetch(res)
其中,fetch() 取一个强制参数,即 res。res 参数定义你要获取的资源,它可以是字符串或任何其他对象,也可以是请求对象。除了强制参数,它还可以取一个可选参数,该参数可以是方法、标头、正文、模式缓存、同源等。
Fetch API VS XMLHttpRequest
以下是 Fetch API 和 XMLHttpRequest 之间的区别:
Difference |
Fetch API |
XMLHttpRequest |
Syntax |
众所周知,Fetch API 是一个基于承诺的 API,因此它提供了更清晰的语法和更好的错误处理方法。 |
XHR 基于回调方法,其语法不如 Fetch API 那么好。 |
Cross-Origin Resource Sharing(CROS) |
Fetch API 明智地处理 CROS 请求,无需任何其他配置。 |
XMLHttpRequest 需要特殊配置来处理或发出跨源请求。 |
Request and Response Header |
Fetch API 提供了更灵活的方法来处理请求和响应标头。 |
XMLHttpRequest 提供了有限数量的方法来处理请求和响应标头。 |
Streaming and Parsing |
Fetch API 为流式传输和解析大型响应提供了良好的支持,因此它提高了性能并减少了内存使用。 |
XMLHttpRequest 需要一个自定义程序来获取此功能。 |
Browser Compatibilities |
Fetch API 是新的,因此旧版本的浏览器可能不支持它。 |
XMLHttpRequest 已使用多年,因此几乎所有浏览器都支持它。 |
Cookies and Credential Control |
Fetch API 对 cookie 和凭据提供了良好的控制,因此与 XMLHttpRequest 相比,我们可以轻松地进行身份验证和授权。 |
XMLHttpRequest 对 cookie 和凭据的支持较少。 |
Timeouts |
Fetch API 不支持超时,因此该请求将继续进行,直到浏览器选择该请求。 |
XMLHttpRequest supports timeouts. |
Fetch API - Browser Compatibility
获取 API 提供了一个现代 JavaScript 接口,用于向服务器发送请求并异步处理来自服务器的响应。与 XMLHttpRequest 对象相比,它更加强大和灵活。
Compatible Browsers
几乎所有现代 Web 浏览器都支持获取 API。以下列表显示了支持获取 API 的浏览器名称及其版本 −
Browser Name |
Versions |
Chrome |
42-117 |
Edge |
14-114 |
Firefox |
39-117 |
Safari |
10.1-16.6 |
Opera |
29-100 |
Chrome Android |
101 |
Firefox for Android |
111 |
Opera Android |
70 |
Safari on IOS |
10.3-16.6 |
Samsung Internet |
4-19 |
Compatibility Check
由于新版本,浏览器兼容性可能会随着时间的推移而改变。因此,这是一个检查当前获取 API 的浏览器兼容性的好方法。以下是用以检查 Web 浏览器兼容性的要点 −
-
Versions of web browser − 在使用获取 API 时,请确保你完全了解使用获取 API 所需的浏览器版本,因为不同版本的 Web 浏览器对获取 API 的支持级别不同。
-
Support of Fetch API − 在使用 Web 浏览器时,请务必验证你正在使用的 Web 浏览器是否支持获取 API。尽管几乎所有现代 Web 浏览器都支持获取 API,但如果你使用的是较旧的浏览器,那么它将不支持获取 API。
-
Feature Detection − 这是一个用于检查当前 Web 浏览器是否支持获取 API 的技术。它创建了一个检查指定获取 API 方法或属性是否存在或可以在当前 Web 浏览器不支持它们的情况下提供备用功能的代码。
-
Cross-Origin Requests − 在使用 Fetch API 时,务必检查当前浏览器是否支持跨源请求。跨源资源共享 (CORS) 策略会对向不同域进行的请求造成直接影响。因此,务必确保你所使用的浏览器包含必要的 CORS 头信息,并且能够妥善处理跨源请求。
-
HTTPS requirement − 有些 Web 浏览器对从 HTTP 来源向 HTTPS 来源创建 Fetch API 请求施加了一些限制。因此,务必检查此类限制并对应用程序进行必要的更改,以便它能够满足所有安全要求。
-
Handling errors − 你所使用的浏览器必须能够正确处理错误和 HTTP 状态代码。确保 Web 浏览器提供了妥善错误处理所需的错误信息。
因此,借助这些要点,我们可以使用 Fetch API 来检查 Web 浏览器的兼容性。
Fetch API - Headers
Fetch API 提供了一个称为 Headers 界面的特殊接口来执行各种操作,例如设置、添加、检索及从请求和响应的 headers 列表中删除 headers。Headers 对象最初是空的,或可能包含零个或多个名称-值对。你可以使用 append() 方法在 headers 对象中添加 header 名称。此界面提供了各种方法对 Headers 对象执行操作。
Syntax
const newHeader = New Headers()
Or
const newHeader = New Headers(init)
Headers() 构造函数仅包含一个可选参数 init。它是一个包含你要预填充你的 headers 对象的 HTTP headers 的对象。此参数的值为字符串值或名称-值对数组。
Example 1
在以下程序中,我们向服务器发送数据。因此,我们使用 Header() 构造函数创建一个新的 headers 对象,然后使用 append() 函数添加名称-值对。然后,我们使用包含 POST 方法、我们之前创建的 headers 对象(用于向请求添加 header)和请求正文的 fetch() 函数发起一个 fetch() 请求。现在,在向服务器发送请求后,我们使用 then() 函数处理响应。如果遇到错误,则 catch() 函数会处理此错误。
<!DOCTYPE html>
<html>
<body>
<script>
// Creating Headers object
const myheaders = new Headers();
// Adding headers to the Headers object
myheaders.append('Content-Type', 'application/json');
myheaders.append('Authorization', 'Bearer token123');
// Sending data using POST request
fetch("https://jsonplaceholder.typicode.com/todos", {
// Adding POST request
method: "POST",
// Adding headers
headers:myheaders,
// Adding body which we want to send
body: JSON.stringify({
id: 32,
title: "Hello! How are you?",
})
})
// Converting received information into JSON
.then(response => response.json())
.then(myData => {
// Display the sent data
console.log("Data Sent Successfully");
// Display output
document.getElementById("manager").innerHTML = JSON.stringify(myData);
});
</script>
<h2>Display Data</h2>
<div>
<!-- Displaying retrevie data-->
<p id = "manager"></p>
</div>
</body>
</html>
Methods
以下是 Header 界面的常用方法 −
Sr.No. |
Method Name & Description |
1 |
Headers.append() 此方法用于在现有标题对象中附加一个新值。或者,如果标题不存在,则可以添加一个标题。 |
2 |
Headers.delete() 此方法用于从 Headers 对象中删除一个标题。 |
3 |
Headers.enteries() 此方法提供一个迭代器,允许我们遍历给定对象中存在的所有键/值对。 |
4 |
Headers.forEach() 此方法对 Headers 对象中存在的每一个键/值对执行一次。 |
5 |
Headers.get() 此方法用于查找 Header 对象中存在的所有标题的所有值的字符串序列。 |
6 |
Headers.getSetCookie() 此方法返回一个数组,其中包含与响应相关的 Set-Cookie 标题的所有值。 |
7 |
Headers.has() 此方法返回一个布尔值,它检查当前 Headers 对象是否包含指定的标题。 |
8 |
Headers.keys() 此方法用于遍历给定对象中存在的所有键/值对的键。 |
9 |
Headers.set() 此方法用于为现有 Headers 对象设置一个新值。或者,如果标题不存在,则添加一个标题。 |
10 |
Headers.values() 此方法用于遍历给定对象中存在的所有键/值对的值。 |
Example 2
在以下程序中,我们使用 Headers 接口提供的 append()、get()、keys() 和 values() 等方法。
<!DOCTYPE html>
<html>
<body>
<script>
// Creating Headers object
const myheaders = new Headers();
// Adding headers to the Headers object
myheaders.append('Content-Type', 'application/json');
myheaders.append('Authorization', 'Bearer token123');
// Sending data using POST request
fetch("https://jsonplaceholder.typicode.com/todos", {
// Adding POST request
method: "POST",
// Adding headers
headers:myheaders,
// Adding body which we want to send
body: JSON.stringify({
id: 32,
title: "Hello! How are you?",
})
})
// Converting received information into JSON
.then(response => {
// Header also returned in response
// Accessing response header
const resHeader = response.headers;
// Getting content type value of the response header
// Using get() function
const contentTypeValue = resHeader.get("Content-Type");
console.log("Content-Type:", contentTypeValue);
// Getting all the keys present in the
// key-value pairs in response header
// Using keys() function
const headerKeys = resHeader.keys();
for(const res of headerKeys){
console.log("Keys:", res);
}
// Getting all the values present in the
// key-value pairs in response header
// Using Values() function
const headerValues = resHeader.values();
for(const resVal of headerValues){
console.log("Values:", resVal);
}
});
</script>
<h2>Fetch API Examples</h2>
</body>
</html>
Fetch API - Request
在 Fetch API 中,Request 接口用于创建资源请求。它是一种替代取回功能(fetch())以外创建请求的方法。它还提供了我们可以应用于请求的各种属性和方法。因此,首先,我们将了解 Request() 构造函数,然后了解如何发送请求,然后了解 Request 接口提供的方法和属性。
Syntax
const newRequest = new Request(resourceURL)
Or
const newRequest = new Request(resourceURL, optional)
Request() 构造函数具有以下参数 −
-
resourceURL − 我们想要提取的资源。它的值可以是资源 URL 或 Request 对象。
-
Options − 提供请求的附加设置的对象,定制选项如下:− method − 表示 GET、POST、PUT 和 DELETE 等请求方法。 headers − 向请求设置标头。 body − 向请求添加数据。此参数未使用 GET 或 HEAD 方法。 mode − 设置请求的模式,例如 cors、same-origin、no-cors 或 navigate。默认情况下,mode 参数的值为 cors。 credentials − 它设置您想要用于请求的凭据,例如 omit、same-origin 或 include。此参数的默认值为 same-origin。 cache − 设置您想要的请求的缓存模式。 redirect − 用于重定向模式,例如 follow、error 或 manual。默认情况下,该参数设置为 follow 值。 referrer − 表示请求参考者的字符串,例如 client、URL 或 no-referrer。此参数的默认值为有关客户端的信息。 referrerPolicy − 用于设置参考者策略。 integrity − 用于设置给定请求的子资源完整性值。 keepalive − 用于检查是否为多个请求/响应创建持久性连接。
-
signal* − 表示与请求通信或中止请求所用的 AbortSignal 对象。 priority − 用于将请求的优先级与其他请求进行比较。此参数的可能值为:
-
-
high − 将当前取回请求的优先级设置为高,高于其他请求。
-
low − 将当前取回请求的优先级设置为低,低于其他请求。
-
auto − 自动查找当前取回请求的优先级。
Send Request
要发送请求,我们必须首先使用 Request 构造函数创建 Request 对象,并带有附加参数,例如标头、正文、方法、资源 URL 等。然后将此对象传递给 fetch() 函数以向服务器发送请求。现在,fetch() 函数返回一个 promise,它将使用响应对象进行解决。如果遇到错误,则执行 catch 块。
Example
在下面的程序中,我们创建了一个使用 Request 对象发送数据的脚本。因此,为此,我们使用 Request() 构造函数创建了一个请求对象,以及以下参数:−
-
URL − 表示资源 URL。
-
method − 在此我们使用 POST 方法,表示我们正在向服务器发送数据。
-
body - 包含我们想要发送的数据。
-
header − 它表示数据是 JSON 数据。
现在我们在`fetch()`函数中传递请求对象以发送请求并处理服务器返回的响应,如果发生错误,则处理该错误。
<!DOCTYPE html>
<html>
<body>
<script>
// Creating request object
const myRequest = new Request("https://jsonplaceholder.typicode.com/todos", {
// Setting POST request
method: "POST",
// Add body which contains data
body: JSON.stringify({
id: 321,
title: "Kirti is a good girl",
}),
// Setting header
headers:{"Content-type": "application/json; charset=UTF-8"}
});
fetch(myRequest)
// Handling response
.then(response => response.json())
.then(myData => {
console.log("Data Sent Successfully");
// Display output
document.getElementById("sendData").innerHTML = JSON.stringify(myData);
})
// Handling error
.catch(err=>{
console.error("We get an error:", err);
});
</script>
<h2>Fetch API Example</h2>
<div>
<!-- Displaying retrieved data-->
<p id="sendData"></p>
</div>
</body>
</html>
Instance Properties
请求接口提供的属性是只读属性。常见的属性如下:
Sr.No. |
Property & Description |
1 |
Request.url 此属性包含给定请求的 URL。 |
2 |
Request.body 此属性包含给定请求的主体。 |
3 |
Request.bodyUsed 此属性用于告知请求中是否存在主体的内容。其值为布尔值。 |
4 |
Request.destination 此属性用于告知请求的目标。 |
5 |
Request.method 此属性包含请求方法,如 GET、POST、PUT 和 DELETE。 |
6 |
Request.headers 此属性包含请求的标头对象。 |
7 |
Request.cache 此属性包含给定请求的缓存模式。 |
8 |
Request.credentials 此属性包含给定请求的凭据。 |
9 |
Request.mode 此属性包含给定请求的模式。 |
Example
在以下程序中,我们使用 Request 接口提供的属性(如 url、method、header 和 mode)。
<!DOCTYPE html>
<html>
<head>
<title>Fetch API Example</title>
</head>
<body>
<h1>Example of Fetch API</h1>
<script>
// Creating request object
const myRequest = new Request("https://jsonplaceholder.typicode.com/todos", {
// Setting POST request
method: "POST",
// Add body which contains data
body: JSON.stringify({
id: 321,
title: "Kirti is a good girl",
}),
// Setting header
headers:{"Content-type": "application/json; charset=UTF-8"},
mode: "cors"
});
// Display url of the request
console.log(myRequest.url);
// Display request method
console.log(myRequest.method);
// Display header of the request
console.log(myRequest.headers.get('content-Type'));
// Display mode of the request
console.log(myRequest.mode);
</script>
</body>
</html>
Methods
以下为 Request 接口中常用的方法:
Sr.No. |
Method & Description |
1 |
Request.arrayBuffer() 此方法用于用请求主体 ArrayBuffer 表示来解决一个承诺。 |
2 |
Request.blob() 此方法用于用请求主体 blob 表示来解决一个承诺。 |
3 |
Request.clone() 此方法用于创建当前请求的副本。 |
4 |
Request.json() 此方法用于将请求主体解析为 JSON,并用解析结果解决一个承诺。 |
5 |
Request.text() 此方法用于用请求主体文本表示来解决一个承诺。 |
6 |
Request.formData() 此方法用于用请求主体 FormData 表示来解决一个承诺。 |
Example
在以下程序中,我们使用 Request 接口提供的属性(如 blob、clone 等)。
<!DOCTYPE html>
<html>
<head>
<title>Fetch API Example</title>
</head>
<body>
<h1>Example of Fetch API</h1>
<script>
// Creating request object
const myRequest = new Request("https://jsonplaceholder.typicode.com/todos");
// Using blob() method
myRequest.blob()
.then(data =>{
console.log(data)
});
// Creating a copy of the request using the clone() method
const duplicate = myRequest.clone();
console.log(duplicate);
</script>
</body>
</html>
Fetch API - Response
Fetch API 提供了一个特殊的接口来创建对请求的响应,并且该接口的名称是响应。此接口提供了一个 Response() 构造函数来创建一个响应对象。它提供各种方法和属性来访问和处理响应数据。
Syntax
const newResponse = New Response()
Or
const newResponse = New Response(rBody)
Or
const newResponse = New Response(rBody, rOption)
Response() 构造函数有以下参数:
-
rBody − 它表示一个定义响应正文的对象。它的值可以为 null(默认值)或 blob、ArrayBuffer、TypedArray、DataView、FormData、String、URLSearchParams、字符串文字或 ReadableStream。
-
Options − 它是一个对象,用于提供我们想要应用于响应的自定义设置,选项如下:
-
headers − 它用于向响应添加标头。默认情况下,此参数的值为空。它的值可以是 Header 对象或字符串的对象文字。
-
status − 此参数表示响应的状态码。它的默认值是 200。
-
statusText − 此参数表示与状态码相关的状态消息,例如“未找到”。它的默认值是“”。
Example
在以下程序中,我们使用 fetch() 函数从给定的 URL 中获取数据,然后以 JSON 格式显示响应数据。
<!DOCTYPE html>
<html>
<body>
<script>
// Data
const option = {message: "Hello Tom. How are you?"};
// creating header object
const newResponse = new Response(JSON.stringify(option), {
status: 200,
statusText:" Receive data successfully"
});
// Displaying response
console.log(newResponse)
</script>
<h2>Fetch API Example</h2>
<div>
<!-- Displaying retrieved data-->
<p id="sendData"></p>
</div>
</body>
</html>
Instance Properties
Response 接口提供的属性是只读属性。因此,常用属性如下:
Sr.No. |
Property & Description |
1 |
Response.body 此属性包含 ReadableStream 正文内容。 |
2 |
Response.ok 此属性检查响应是否成功。此属性的值为布尔值。 |
3 |
Response.bodyUsed 此属性用于检查正文是否在响应中使用。它的值为布尔值。 |
4 |
Response.redirected 此属性用于检查响应是否是重定向的结果。它的值为布尔值。 |
5 |
Response.status 此属性包含响应状态代码。 |
6 |
Response.statusText 此属性根据状态码提供状态消息。 |
7 |
Response.type 此属性提供响应类型。 |
8 |
Response.url 此属性提供响应的 URL。 |
9 |
Response.header 此属性提供给定响应的标头对象。 |
Example
在下面的程序中,我们使用 Response 接口提供的属性。
<!DOCTYPE html>
<html>
<body>
<h2>Fetch API Example</h2>
<script>
// GET request using fetch()function
fetch("https://jsonplaceholder.typicode.com/todos")
.then(response => {
// Finding response URL
console.log("URL is: ", response.url);
// Getting response text
console.log("Status Text: ", response.statusText);
// Getting response status
console.log("Status Code: ", response.status);
}).catch(err =>{
// Handling error
console.log("Found Error:", err);
});
</script>
</body>
</html>
Methods
以下是 Response 接口常用的方法 −
Sr.No. |
Method & Description |
1 |
Request.arrayBuffer() 此方法用于返回一个承诺,该承诺将使用响应体的 ArrayBuffer 表示形式进行解析。 |
2 |
Request.blob() 此方法用于返回一个承诺,该承诺将使用响应体的 blob 表示形式进行解析。 |
3 |
Request.clone() 此方法用于创建当前响应对象的副本。 |
4 |
Request.json() 此方法用于将响应体解析为 JSON 并返回一个承诺,该承诺将使用解析的结果进行解析。 |
5 |
Request.text() 此方法用于返回一个承诺,该承诺将使用响应体的文本表示形式进行解析。 |
6 |
Request.formData() 此方法用于返回一个承诺,该承诺将使用响应体的 FormData 表示形式进行解析。 |
7 |
Response.error() 此方法返回一个与网络错误相关的新 Response 对象。它是一个静态方法。 |
8 |
Response.redirect 此方法返回一个具有不同 URL 的新 Response 对象。它是一个静态方法。 |
9 |
Response.json() 此方法返回一个用于返回 JSON 编码数据的新 Response 对象。它是一个静态方法。 |
Example
在下面的程序中,我们使用 Response 接口提供的方法。因此,我们将在此处使用 json() 函数以 JSON 格式解析响应。
<!DOCTYPE html>
<html>
<body>
<script>
// GET request using fetch()function
fetch("https://jsonplaceholder.typicode.com/todos/2", {
// Method Type
method: "GET"})
// Parsing the response data into JSON
// Using json() function
.then(response => response.json())
.then(myData => {
// Display output
document.getElementById("manager").innerHTML = JSON.stringify(myData);
}).catch(newError =>{
// Handling error
console.log("Found Error:", newError)
});
</script>
<h2>Display Data</h2>
<div>
<!-- Displaying retrevie data-->
<table id = "manager"></table>
</div>
</body>
</html>
Fetch API - Body Data
Fetch API 是现代技术,可异步发送或接收数据,而无需刷新网页。它提供了一个在 Web 浏览器中创建 HTTP 请求的接口。它几乎被所有现代 Web 浏览器所支持。我们还可以说,通过使用 Fetch API,我们可以从 Web 服务器获取诸如 JSON 数据、HTML 页面等资源,并可以使用不同的 HTTP 请求(如 PUT、POST 等)将数据发送到服务器。因此,在本文中,我们将了解什么是正文数据以及我们如何使用正文数据。
Body Data
在 Fetch API 中,请求和响应都包含正文数据。请求中的正文数据是一个实例,其中包含我们要发送到服务器的数据,而响应中的正文数据是一个实例,其中包含用户请求的数据。它通常由 PUT 或 POST 请求用于向服务器发送数据。它可以是 ArrayBuffer、TypedArray、DataView、Blob、文件、字符串、URLSearchParams 或 FormData 的实例。在发送正文数据时,还需要在请求中设置一个标头,以便服务器知道数据的类型是什么。
Request 和 Response 接口提供了各种方法来提取正文,它们是 −
-
Request. arrayBuffer() − 此方法用于解决 ArrayBuffer 表示请求正文的承诺。
-
Request.blob() − 此方法用于解决 blob 表示请求正文的承诺。
-
Request.formData() − 此方法用于解决 formData 表示请求正文的承诺。
-
Request.json() − 此方法用于解析请求正文为 JSON 并解决解析结果的承诺。
-
Request.text() − 此方法用于解决具有请求正文的文本表示的承诺。
-
Response.arrayBuffer() − 此方法用于返回一个 promise,它将解决一个 ArrayBuffer 表示的响应正文。
-
Response.blob() − 此方法用于返回一个 promise,它将解决一个 Blob 表示的响应正文。
-
Response.formData() - 此方法用于返回一个 promise ,该 promise 可用作响应正文的 FormData 表示形式解析出来。
-
Response.json() - 此方法用于将响应正文解析为 JSON,并返回一个 promise 以根据解析结果解析出来。
-
Response.text() - 此方法用于返回一个 promise ,该 promise 可用作响应正文的文本表示形式解析出来。
所有这些方法均返回一个 promise ,该 promise 可用作实际正文内容解析出来。
正文数据通常与 fetch() 函数一起使用。在本文档中,您不必非用正文参数不可,只有在要向服务器发送数据时才可以使用该参数。
Syntax
fetch(resourceURL,{
Method: 'POST',
body:{
Name: "Monika",
Age: 34,
City: "Pune"
},
headers: {'content-Type':'application/json'}
})
fetch() 函数的参数 -
-
resourceURL - 它表示我们希望获取的资源。它可以是字符串、请求对象或资源的 URL。
-
method - 它表示请求方法,例如 GET、POST、PUT 和 DELETE。
-
headers - 它用于向您的请求添加 header。
-
body - 它用于向您的请求添加数据。GET 或 HEAD 方法不使用它。
在以下程序中,我们使用 POST 方法发送正文数据。因此,我们创建了一个 HTML 代码,在该代码中,我们使用 JavaScript 脚本向服务器发送数据。在脚本中,我们定义了一个 fetch() 函数,该函数使用 POST 请求方法将正文参数中存在的数据发送到指定的 URL。此处将标头设置为 “application/json”,表示我们正在发送数据。在向服务器发送请求之前,我们会借助 JSON.stringify() 函数将数据转换成 JSON 字符串。在收到服务器的响应后,我们检查响应是否正常。如果是,则我们使用 response.json() 函数将响应正文解析成 JSON,然后在输出屏幕上显示结果。如果遇到任何错误,则 catch() 块会处理该错误。
Example
<!DOCTYPE html>
<html>
<body>
<script>
// Retrieving data from the URL using the POST request
fetch("https://jsonplaceholder.typicode.com/todos", {
// Adding POST request
method: "POST",
// Adding body which we want to send
body: JSON.stringify({
id: 45,
title: "Tom like finger chips",
age: 34
}),
// Adding header
headers:{"Content-type": "application/json; charset=UTF-8"}
})
// Converting received information into JSON
.then(response =>{
if (response.ok){
return response.json()
}
})
.then(myData => {
// Display the retrieve Data
console.log("Data Sent Successfully");
// Display output
document.getElementById("sendData").innerHTML = JSON.stringify(myData);
}).catch(err=>{
console.log("Found error:", err)
});
</script>
<h2>Sent Data</h2>
<div>
<!-- Displaying retrevie data-->
<p id = "sendData"></p>
</div>
</body>
</html>
Fetch API - Credentials
在 Fetch API 中,Cookie、授权标头和 TLS 客户端证书称为凭据。我们还可以说凭据是数字文档(如密码、用户名、证书等),用于确认用户或客户端在向服务器发出请求时的身份。
让我们在下面更详细地了解这些凭据 −
Cookies − 它们是由 Web 浏览器存储并随所有相同来源请求发送的小块数据。它用于存储会话信息、经常使用的数据等。它们还控制他们的会话、范围和可访问性。Cookie 也由服务器借助 Set-Cookie 标头发送。
Authorization Headers − 这些包括包含身份验证信息(如密码、用户名、密钥等)的那些 HTTP 标头。授权标头用于实现各种授权架构,服务器也会使用散列、加密等各种方法对其进行验证。
TLS Client Certificates − 它们是认证机构提供的数字证书,也安装在客户端设备上。它们用于在使用传输层安全性的情况下创建与服务器的安全连接时提供客户端的身份证明。
Syntax
fetch(resourceURL, {credentials:"include"})
此属性可以具有以下三个值中的一个值 −
omit − 当 credentials 属性的值设置为 omit 时,表示浏览器将从请求中删除所有凭据,并忽略响应中发送的凭据。
same-origin − 当 credentials 属性的值设置为 same-origin 时,表示浏览器将凭据包含在向请求页面相同来源发出的那些请求中。并且只使用来自相同来源 URL 的那些凭据。这是此属性的默认值。
include − 当 credentials 属性的值设置为 include 时,表示浏览器将在同源请求和跨源请求中同时包含凭据,并且始终使用响应中发送的那些凭据。
Example 1
在以下程序中,我们使用 fetch() 函数对给定的 URL 发出请求。此处我们将 credentials 属性设置为 “include” 值,它表示请求中包含跨源和同源凭据。在向服务器发送请求后,现在我们使用 then() 函数来处理响应。如果遇到错误,则错误由 catch() 函数处理。
<!DOCTYPE html>
<html>
<body>
<script>
// Retrieving data from the URL using a GET request
fetch("https://jsonplaceholder.typicode.com/todos/21", {
// Sending both same-origin and
// cross-origin credentials
credentials: "include"
})
// Converting received data into text
.then(response => response.text())
.then(myData => {
// Display the retrieve Data
console.log(myData);
})
.catch(err=>{
// Cach error if occur
console.log("Found Error:", err)
});
</script>
<h2>Fetch API Example</h2>
</body>
</html>
Example 2
在以下程序中,我们使用 fetch() 函数对给定的 URL 发出请求。此处我们将 credentials 属性设置为 “same-oigin” 值,这意味着凭据仅包含在发往同一 source 或域的请求中。在向服务器发送请求后,现在我们使用 then() 函数来处理响应。如果遇到错误,则错误由 catch() 函数处理。
<!DOCTYPE html>
<html>
<body>
<script>
// Retrieving data from the URL using a GET request
fetch("https://jsonplaceholder.typicode.com/todos/21", {
// Sending credentials only for the same domain request
credentials: "same-origin"
})
// Converting received data into text
.then(response => response.text())
.then(myData => {
// Display the retrieve Data
console.log(myData);
})
.catch(err=>{
// Cach error if occur
console.log("Found Error:", err)
});
</script>
<h2>Fetch API Example</h2>
</body>
</html>
Fetch API - Send GET Requests
Fetch API 提供了一个界面来异步管理与 Web 服务器之间的请求和响应。它提供一个 fetch() 方法来获取资源或将请求异步发送至服务器,而无需刷新网页。使用 fetch() 方法,我们可以执行多种请求,如 POST、GET、PUT 和 DELETE。在本文中,我们将学习如何使用 Fetch API 发送 GET 请求。
Send GET Request
GET 请求是一个 HTTP 请求,用于从给定资源或 Web 服务器检索数据。在 Fetch API 中,我们可以通过在 fetch() 函数中指定方法类型或不指定任何 fetch() 函数方法类型来使用 GET 请求。
Syntax
fetch(URL, {method: "GET"})
.then(info =>{
// Code
})
.catch(error =>{
// catch error
});
在此处,我们在 fetch() 函数中指定方法类型为 GET 请求。
或
fetch(URL)
.then(info =>{
// Code
})
.catch(error =>{
// catch error
});
在此处,我们没有在 fetch() 函数中指定任何方法类型,因为 fetch() 函数默认使用 GET 请求。
Example
在以下程序中,我们将从给定 URL 中检索 id 和标题,并将其显示在表格中。因此,为此,我们使用 URL 定义一个 fetch() 函数,从该 URL 中检索数据并执行 GET 请求。此函数将从给定 URL 检索数据,然后使用 response.json() 函数将数据转换为 JSON 格式。之后,我们将在表中显示检索到的数据,即 id 和标题。
<!DOCTYPE html>
<html>
<body>
<script>
// GET request using fetch()function
fetch("https://jsonplaceholder.typicode.com/todos", {
// Method Type
method: "GET"})
// Converting received data to JSON
.then(response => response.json())
.then(myData => {
// Create a variable to store data
let item = `<tr><th>Id</th><th>Title</th></tr>`;
// Iterate through each entry and add them to the table
myData.forEach(users => {
item += `<tr>
<td>${users.id} </td>
<td>${users.title}</td>
</tr>`;
});
// Display output
document.getElementById("manager").innerHTML = item;
});
</script>
<h2>Display Data</h2>
<div>
<!-- Displaying retrevie data-->
<table id = "manager"></table>
</div>
</body>
</html>
Fetch API - Send POST Requests
Fetch API 与 XMLHttpRequest 类似,它也提供了一个 JavaScript 接口,用于管理与 Web 服务器之间的异步请求和响应。它提供了 fetch() 方法,用于提取资源或向服务器发送异步请求,而无需重新加载网页。借助 fetch() 方法,我们可以执行各种请求,如 POST、GET、PUT 和 DELETE。因此,在本文中,我们将了解如何借助 Fetch API 发送 POST 请求。
Send POST Request
Fetch API 也支持 POST 请求。POST 请求是一种 HTTP 请求,用于将数据或窗体发送到给定的资源或 Web 服务器。在 Fetch API 中,我们可以使用 POST 请求,方法是指定其他参数,如方法、正文标头等。
Syntax
fetch(URL, {
method: "POST",
body: {//JSON Data},
headers:{"content-type": "application/json; charset=UTF-8"}
})
.then(info =>{
// Code
})
.catch(error =>{
// catch error
});
此处,fetch() 函数包含以下参数 −
-
URL − 它表示我们要获取的资源。
-
method − 它是一个可选参数。它用于表示像 GET、POST、DELETE 和 PUT 这样的请求。
-
body − 它也是一个可选参数。当您希望向请求添加正文时,可以使用此参数。
-
header − 它也是一个可选参数。它用于指定标头。
Example
在以下程序中,我们将一个 JSON 文档发送到给定的 URL。为此,我们需要定义一个 fetch() 函数以及一个 URL,一个 POST 请求,一个正文(即 JSON 文档)和一个标头。因此,当 fetch() 函数执行时,它会将给定的正文发送到指定的 URL,并将响应数据转换成 JSON 格式,使用 response.json() 函数。之后,我们将显示响应。
<!DOCTYPE html>
<html>
<body>
<script>
// Retrieving data from the URL using POST request
fetch("https://jsonplaceholder.typicode.com/todos", {
// Adding POST request
method: "POST",
// Adding body which we want to send
body: JSON.stringify({
id: 32,
title: "Hello! How are you?",
}),
// Adding headers
headers:{"Content-type": "application/json; charset=UTF-8"}
})
// Converting received information into JSON
.then(response => response.json())
.then(myData => {
// Display the retrieve Data
console.log("Data Sent Successfully");
// Display output
document.getElementById("manager").innerHTML = myData;
});
</script>
<h2>Display Data</h2>
<div>
<!-- Displaying retrevie data-->
<table id = "manager"></table>
</div>
</body>
</html>
Fetch API - Send PUT Requests
在获取 API 中,PUT 请求用于更新或替换服务器上的现有资源或数据。使用 PUT 请求通常包含你要在请求主体中更新的数据。当服务器收到请求时,服务器使用该数据更新给定 URL 中存在的现有资源。如果服务器不包含该资源,则它将使用给定数据创建新资源。
Syntax
fetch(URL, {
method: "PUT",
body: {//JSON Data},
headers:{"content-type": "application/json; charset=UTF-8"}})
.then(info =>{
// Code
})
.catch(error =>{
// catch error
});
此处,fetch() 函数包含以下参数 −
-
URL − 它表示我们要获取的资源。
-
method − 它是一个可选参数。它用于表示像 GET、POST、DELETE 和 PUT 这样的请求。
-
body − 它也是一个可选参数。当您希望向请求添加正文时,可以使用此参数。
-
headers − 它也是一个可选参数。用于指定标头。
Example 1: Sending PUT Request Using fetch()
在下面的程序中,我们创建一个简单的脚本,以使用 PUT 请求通过 fetch() 函数更新给定 URL 中的现有数据。在这里,我们连同标题一起在给定 URL 中发送 JSON 文档。因此在收到响应后,检查响应的状态。如果响应状态为 200,则表示数据已成功更新。如果发生错误,则 catch 函数处理该错误。
<!DOCTYPE html>
<html>
<head>
<title>Fetch API Example</title>
</head>
<body>
<h1>Example of Fetch API</h1>
<script>
// Update data in the URL using the PUT request
fetch("https://jsonplaceholder.typicode.com/todos/21", {
// Using PUT request
method: "PUT",
// Body contains replacement data
body: JSON.stringify({
id: 22,
title: "Hello! Mohina what are you doing?",
}),
// Setting headers
headers:{"Content-type": "application/json; charset=UTF-8"}
})
.then(response => {
// Handle response
if (response.status == 200){
console.log("Data updated successfully")
} else {
throw new error("Error Found:", response.status)
}
})
// Handle error
.catch(err=>{
console.error(err)
});
</script>
</body>
</html>
Example 2: Sending PUT Request Using fetch() with async/await
在下面的程序中,我们创建一个脚本,以通过 fetch() 函数和 async/await 使用 PUT 请求更新给定 URL 中的现有数据。在这里,我们连同标题一起在给定 URL 中发送 JSON 文档。因此,我们创建一个名为 modifyData() 的异步函数。在此处,我们将 await 关键字与 fetch() 函数一起使用,以暂停函数的执行,直到返回的承诺得到解决。收到响应后,检查响应的状态,如果响应状态为 200,则表示数据已成功更新。如果发生错误,则 catch 函数处理该错误。
Note − 在此处,async/await 一起用于以同步方式处理异步操作。
<!DOCTYPE html>
<html>
<head>
<title>Fetch API Example</title>
</head>
<body>
<h1>Example of Fetch API</h1>
<script>
async function modifyData(){
try{
const myRes = await fetch("https://jsonplaceholder.typicode.com/todos/21", {
// Using PUT request
method: "PUT",
// Body contains replacement data
body: JSON.stringify({
id: 24,
title: "Mina leaves in Delhi",
})
});
// Handling response
if (myRes.status == 200){
console.log("Data updated successfully")
} else {
throw new error("Error Found:", myRess.status)
}
} catch(err){
console.error(err)
}
}
// Calling the function
modifyData();
</script>
</body>
</html>
Fetch API - Send JSON Data
Fetch API 用于异步发送或接收数据,而无需刷新网页。在 Fetch API 中,我们可以发送各种格式的数据,如 JSON、URL 编码表单、Text、FormData、Blob 或 ArrayBuffer。在所有这些格式中,JSON(JavaScript 对象表示法)数据是使用 Fetch 发送数据时最常用的格式,因为它简单、轻量,并且与大多数编程语言兼容。JSON 数据通常按以下格式创建 −
Const JSONData = {
name: "Monika",
Id: 293,
Age: 32,
City: "Pune"
};
其中 name、id、Age 和 City 是属性,而 Monika、293、32 和 Pune 是其值。
Fetch API 通常将 JSON 数据作为有效负载发送到请求正文中,或者可以接收响应正文中的内容。而数据被序列化为字符串,因为这便于在系统之间传输数据。
在使用 JSON 数据时,Fetch API 对 JSON 数据执行两个主要操作 −
Serializing − 在请求中发送 JSON 数据时,我们需要使用 “JSON.stringify()” 函数将值转换为 JSON 字符串格式。该函数将对象或值作为输入参数,并返回表示 JSON 格式的字符串。由于要序列化数据,因此我们可以轻松地在网络上传输数据。
Syntax
JSON.stringify()
Parsing − 解析是一个过程,在此过程中,我们将响应中接收的 JSON 字符串转换回 JavaScript 对象或值。这种 JSON 数据解析可以通过使用 response.json() 函数来完成。该函数以响应对象作为参数,并返回一个 promise,该 promise 将解析为解析后的 JSON 数据或 JavaScript 对象。
Send JSON Data
要发送 JSON 数据,Fetch API 使用以下方法 −
-
Using fetch() function
-
使用带有 async/await 的 fetch() 函数
-
Using request object
Method 1 − Using the fetch() function
我们可以使用 fetch() 函数发送数据。在此函数中,我们在 body 参数中创建 JSON 数据,并使用 POST 请求方法在指定 URL 上发送数据。
Example
在以下程序中,我们将使用 fetch() 函数发送 JSON 数据。fetch() 函数用于创建请求。请求包含 POST 方法,它告诉我们我们想要发送数据,一个正文,其中包含使用 stringify() 转换为字符串的 JSON 数据,和一个标头,它指定我们正在发送 JSON 数据。在发送请求后,服务器返回一个将解析为响应对象的 promise,并使用 .json() 解析 JSON 数据,并将结果显示在控制台日志中。如果遇到错误,则错误由 catch 块处理。
<!DOCTYPE html>
<html>
<body>
<script>
// Sending JSON data using a POST request
fetch("https://jsonplaceholder.typicode.com/todos", {
// Setting POST request
method: "POST",
// Add a body which contains JSON data
body: JSON.stringify({
id: 290,
title: "Today is the rainy day",
}),
// Setting headers
headers:{"Content-type": "application/json; charset=UTF-8"}
})
// Converting response to JSON
.then(response => response.json())
.then(myData => {
console.log("Data Sent Successfully");
// Display output in HTML page
document.getElementById("sendData").innerHTML = JSON.stringify(myData);
})
.catch(err=>{
console.error("We get an error:", err);
});
</script>
<h2>Sent Data</h2>
<div>
<!-- Displaying data-->
<p id = "sendData"></p>
</div>
</body>
</html>
Method 2 − Using fetch() function with async/await
我们还可以使用带有 async/await 的 fetch() 函数发送 JSON 数据。Async/await 允许你创建异步程序,该程序的行为更像同步程序,这使得学习和理解更加容易。
Example
在以下程序中,我们将使用带有 async/await 的 fetch() 函数发送 JSON 数据。因此,为此,我们创建了一个 async 函数。在函数中,我们使用 try 块,该块使用 fetch() 函数以及资源 URL、POST 请求方法、标头和 body(字符串格式的 JSON 数据)参数将 JSON 数据发送到给定 URL。它还将 await 关键字与 fetch() 函数一起使用,该关键字用于等待来自服务器的响应。如果响应成功,那么我们使用 .json() 函数解析服务器返回的响应。如果响应的状态代码包含一个不成功代码,则 else 块运行。如果我们在获取操作期间遇到错误,则该错误由 catch 块处理。
<!DOCTYPE html>
<html>
<body>
<script>
async function sendingJSONData(){
try{
const retrunResponse = await fetch("https://jsonplaceholder.typicode.com/todos", {
// Setting POST request to send data
method: "POST",
// Add body which contains JSON data
body: JSON.stringify({
id: 290,
title: "Today is the rainy day",
}),
// Setting headers
headers:{"Content-type": "application/json; charset=UTF-8"}
});
if (retrunResponse.ok){
// Handling response
const returnData = await retrunResponse.json();
console.log("Data send Successfully");
// Display output in HTML page
document.getElementById("sendData").innerHTML = JSON.stringify(returnData);
} else {
console.log("We found error", retrunResponse.status);
}
} catch(err) {
// Handling error if occur
console.error("Error is:", err)
}
}
sendingJSONData();
</script>
<h2>Sent Data</h2>
<div>
<!-- Displaying data-->
<p id = "sendData"></p>
</div>
</body>
</html>
Method 3 − Using request object
我们还可以使用请求对象发送 JSON 数据。它是一种替代 fetch() 函数,用于向服务器发送请求。请求对象还使用 POST 方法在指定 URL 上发送 JSON 数据。请求对象是通过使用 Request 接口的 Request() 构造函数创建的。请求对象在通过 fetch() 函数发送请求之前提供了更大的灵活性来创建或配置请求。它还允许我们添加其他选项,如标头、缓存、请求方法等。
Example
在以下程序中,我们将使用请求对象发送 JSON 数据。因此,使用 Request() 构造函数,我们创建一个请求对象以及参数,如资源 URL、POST 请求方法、body(使用 stringify() 的字符串格式的 JSON 数据)和标头。现在我们将 newRequest 对象传递到 fetch 函数中以发送请求并使用 .then() 函数处理响应,并使用 .json() 解析响应。如果我们在获取操作期间遇到错误,则该错误由 catch 块处理。
<!DOCTYPE html>
<html>
<body>
<script>
// Creating request object
const newRequest = new Request("https://jsonplaceholder.typicode.com/todos", {
// Setting POST request
method: "POST",
// Add body which contains JSON data
body: JSON.stringify({
id: 290,
title: "Today is the rainy day. I like rain",
}),
// Setting headers
headers:{"Content-type": "application/json; charset=UTF-8"}
});
fetch(newRequest)
// Handling response
.then(response => response.json())
.then(myData => {
console.log("Data Sent Successfully");
// Display output in HTML page
document.getElementById("sendData").innerHTML = JSON.stringify(myData);
})
// Handling error
.catch(err=>{
console.error("We get an error:", err);
});
</script>
<h2>Sent Data</h2>
<div>
<!-- Displaying data-->
<p id = "sendData"></p>
</div>
</body>
</html>
Fetch API - Send Data Objects
在 Fetch API 中,我们可以将数据对象从 Web 浏览器发送到 Web 服务器。数据对象是一个包含键值对或属性值对的数据对象。或者我们可以说数据对象是我们使用 Fetch API 创建 HTTP 请求时添加到请求正文中的数据。
Fetch API 支持各种数据格式;你可以根据设置的内容类型标头或服务器的要求对其进行选择。一些常用的数据格式为 −
JSON
JSON 被称为 JavaScript 对象表示法。它是 Web 浏览器和服务器之间交换数据的最常用数据格式。在 JSON 格式中,数据以键值对的形式存储,并为嵌套对象或数组提供完全支持。要以 JSON 格式发送数据,我们需要使用 “JSON.stringfy()” 函数将 JavaScript 对象转换成 JSON 字符串。
以下是数据 JSON 格式 −
const newData = {
empName: "Pooja",
empID: 2344,
departmentName: "HR"
};
其中,“empName”、“empID”和“department”是键,“Pooja”、“2344”和“HR”是它们的值。
以下标头用于 JSON 格式 −
headers:{"Content-type": "application/json; charset=UTF-8"}
它告诉服务器收到的数据为 JSON 格式。
Example
在以下程序中,我们创建了一个脚本,以 JSON 格式发送数据。因此,为此,我们创建了一个具有键值对的数据对象。现在我们使用 fetch() 函数向服务器发送请求。在此获取函数中,我们包含请求方法 “POST”,将标头设置为 “application/json”,该标头告诉服务器发送的数据为 JSON,并将数据对象包括在请求正文中,方法是使用 “JSON.stringify()” 函数转换为 JSON 字符串。向服务器发送请求后,现在我们使用 then() 函数来处理响应。如果遇到错误,则该错误将由 catch() 函数处理。
<!DOCTYPE html>
<html>
<body>
<script>
// Data object
const newData = {
id: 45,
title: "Tom like finger chips",
age: 34
};
fetch("https://jsonplaceholder.typicode.com/todos", {
// Adding POST request to send data
method: "POST",
// Adding header
headers:{"Content-type": "application/json; charset=UTF-8"},
// Adding body which we want to send
// Here we convert data object into JSON string
body: JSON.stringify(newData)
})
// Converting received information into JSON
.then(response =>{
if (response.ok){
return response.json()
}
})
.then(myData => {
// Display result
console.log("Data Sent Successfully");
// Display output
document.getElementById("sendData").innerHTML = JSON.stringify(myData);
}).catch(err=>{
console.log("Found error:", err)
});
</script>
<h2>Sent Data</h2>
<div>
<!-- Displaying data-->
<p id = "sendData"></p>
</div>
</body>
</html>
FormData
FormData 是内置的 JavaScript 对象。它用于以 HTML 表单格式发送数据。在 FormData 中,我们可以以键值对的形式存储数据,其中键表示表单的字段,值表示该字段的值。它可以处理二进制数据、文件和其他表单类型。要创建新的表单对象,我们需要使用 FormData() 构造函数以及一个新关键字。
Syntax
newform.append("name", "Mohina");
其中,“name”是表单的键或字段,而“Mohina”是字段的值。使用 Fetch API 中的 FormData 对象时,我们不需要设置头部,因为 Fetch API 将自动为 FormData 对象设置头部。
Example
在以下程序中,我们创建一个脚本来发送 FormData 中的数据。为此,我们使用 FormData() 构造函数创建一个 FormData 对象,然后使用 append() 函数在 FormData 对象中添加键值对。现在,我们使用 fetch() 函数向服务器发送请求。在此 fetch 函数中,我们包括请求方法“POST”,并将 FormData 对象包含在 body 参数中。在向服务器发送请求后,我们现在使用 then() 函数来处理响应。如果遇到错误,则该错误将由 catch() 函数处理。
<!DOCTYPE html>
<html>
<body>
<script>
// FormData object
const newform = new FormData();
// Adding key-value pairs in FormData object
newform.append("id", 4532);
newform.append("title", "Today is raining");
fetch("https://jsonplaceholder.typicode.com/todos", {
// Adding POST request to send data
method: "POST",
// Adding body which we want to send
// Here we add FormData object
body: newform
})
// Converting received information into JSON
.then(response =>{
if (response.ok){
return response.json()
}
})
.then(myData => {
// Display result
console.log("Data Sent Successfully");
// Display output in HTML page
document.getElementById("sendData").innerHTML = JSON.stringify(myData);
}).catch(err=>{
console.log("Found error:", err)
});
</script>
<h2>Sent Data</h2>
<div>
<!-- Displaying data-->
<p id = "sendData"></p>
</div>
</body>
</html>
Plain Text
在 Fetch API 中,我们还可以以简单的纯文本发送数据。如果我们要发送原始文本或非标准数据格式,那么我们将使用纯文本发送数据。要发送纯文本,我们需要简单地在请求的正文中以字符串形式添加文本。
以下是纯文本对象:
const newData = "My car is running very fast"
纯文本使用以下头部:
headers:{"Content-type": "text/plain"}
它向服务器指示接收到的数据为纯文本。
Example
在以下程序中,我们创建一个脚本,以纯文本发送数据。为此,我们创建一个数据对象,并在纯文本中为其分配字符串值。现在,我们使用 fetch() 函数向服务器发送请求。在此 fetch 函数中,我们包括请求方法“POST”,将头部设置为“text/plain”(这告诉服务器发送的数据为纯文本),并将数据对象包含在请求的正文中。在向服务器发送请求后,我们现在使用 then() 函数来处理响应。如果遇到错误,则该错误将由 catch() 函数处理。
<!DOCTYPE html>
<html>
<body>
<script>
// FormData object
const newform = new FormData();
// Adding key-value pairs in FormData object
newform.append("id", 4532);
newform.append("title", "Today is raining");
fetch("https://jsonplaceholder.typicode.com/todos", {
// Adding POST request to send data
method: "POST",
// Adding body which we want to send
// Here we add the FormData object
body: newform
})
// Converting received information into JSON
.then(response =>{
if (response.ok){
return response.json()
}
})
.then(myData => {
// Display result
console.log("Data Sent Successfully");
// Display output in HTML page
document.getElementById("sendData").innerHTML = JSON.stringify(myData);
}).catch(err=>{
console.log("Found error:", err)
});
</script>
<h2>Sent Data</h2>
<div>
<!-- Displaying data-->
<p id = "sendData"></p>
</div>
</body>
</html>
URL-encoded Data
URL 编码的数据是用于在 URL 参数或 POST 请求正文中发送表单的最常使用的数据格式。它将数据表示为键值对的形式,其中使用百分号编码对值进行编码。我们可以借助 URLSearchParams 类创建 URL 编码数据对象。
Syntax
newform.append("name", "Mohina");
其中,“name”是表单的键或字段,而“Mohina”是字段的值。
URL 编码的数据使用以下头部:
headers:{"Content-type": "text/plain"}
它向服务器指示接收到的数据为 URL 编码数据。
Example
在以下程序中,我们创建一个脚本,以纯 URL 编码发送数据。为此,我们使用 URLSearchParams() 创建一个数据对象,并使用 append() 函数分配键值对。现在,我们使用 fetch() 函数向服务器发送请求。在此 fetch 函数中,我们包括请求方法“POST”,将头部设置为“application/x-www-form-urlencoded”(这告诉服务器发送的数据为 URL 编码格式),并将数据对象包含在请求的正文中。在向服务器发送请求后,我们现在使用 then() 函数来处理响应。如果遇到错误,则该错误将由 catch() 函数处理。
<!DOCTYPE html>
<html>
<body>
<script>
// FormData object
const newform = new FormData();
// Adding key-value pairs in FormData object
newform.append("id", 4532);
newform.append("title", "Today is raining");
fetch("https://jsonplaceholder.typicode.com/todos", {
// Adding POST request to send data
method: "POST",
// Adding body which we want to send
// Here we add FormData object
body: newform
})
// Converting received information into JSON
.then(response =>{
if (response.ok){
return response.json()
}
})
.then(myData => {
// Display result
console.log("Data Sent Successfully");
// Display output in HTML page
document.getElementById("sendData").innerHTML = JSON.stringify(myData);
}).catch(err=>{
console.log("Found error:", err)
});
</script>
<h2>Sent Data</h2>
<div>
<!-- Displaying data-->
<p id = "sendData"></p>
</div>
</body>
</html>
Fetch API - Custom Request Object
在 Fetch API 中,我们还可以借助 Request 接口的 Request() 构造函数创建自定义 Request 对象。Request 接口为我们提供了对 HTTP 请求的更多控制和灵活性。它提供了多种选项,如 URL、方法、主体、标头等,帮助我们创建定制的 HTTP 请求。在创建自定义请求对象之前,我们首先了解 Request() 构造函数,我们可以使用它来创建 Request 对象。
Request() Constructor
为了创建一个请求对象,我们可以使用 Request() 构造函数以及一个 new 关键字。该构造函数包含一个必需参数,即资源的 URL,另一个参数是可选的。
Syntax
const newRequest = New Request(resourceURL)
Or
const newRequest = New Request(resourceURL, optional)
Request() 构造函数具有以下参数 −
-
resourceURL − 它表示我们要获取的资源。它可以是资源的 URL 或 Request 对象。
-
Options - 它是一个用于提供希望在请求中应用的自定义设置的对象,选项如下 -
-
method - 它表示请求方法,例如 GET、POST、PUT 和 DELETE。
-
headers - 它用于向您的请求添加 header。
-
body - 它用于向您的请求添加数据。GET 或 HEAD 方法不使用它。
-
mode - 它表示希望用于请求的模式。此参数的值可以是 cors、same-origin、no-cors 或 navigate。默认情况下,mode 参数的值为 cors。
-
credentials - 它表示希望在请求中使用的认证信息。此参数的默认值是 same-origin,但还可以根据需要使用 omit、same-origin 或 include 等值。
-
cache - 它代表你希望请求的缓存模式。
-
redirect - 它用于重定向模式。此参数的值可以是:follow、error 或 manual。默认情况下,此参数设置为 follow 值。
-
referrer - 它表示指定请求引荐来源的字符串。此参数的可能值为 client、URL 或 no-referrer。此参数的默认值为 client。
-
referrerPolicy - 它用于指定引荐来源策略。
-
integrity - 它用于表示给定请求的子资源完整性值。
-
keepalive - 它包含一个布尔值,以确定是否为多个请求/响应创建持久连接。
-
signal - 它包含一个 AbortSignal 对象,用于与请求通信或取消请求。
-
priority - 它用于指定请求与其他请求相比的优先级。此参数可以具有以下任何一个值 -
-
high - 如果希望将当前获取请求的优先级设置为高于其他请求。
-
low - 如果希望将当前获取请求的优先级设置为低于其他请求。
-
auto - 自动查找当前获取请求的优先级,高于其他请求。
Custom Request object
要创建一个自定义请求对象,我们需要执行以下步骤 -
Step 1 - 自定义 Request 选项
optional ={
method: "POST",
headers: {"Content-Type": "application/json"},
body = {
Name: "Tom",
Age: 23}
};
Step 2 - 使用 Request() 构造函数创建一个自定义请求对象。
const newRequest = new Request(resourceURL, optional
Step 3 - 使用 fetch() 函数获取请求对象。
fetch(newRequest)
.then(response =>{
// Handling the response
}).catch(err => {
// Handle error
})
Example
在以下程序中,我们创建了一个使用自定义 Request 对象发送数据的脚本。因此,为此,我们使用 Request() 构造函数创建了一个自定义请求对象,它接受两个参数:URL(资源 URL)和可选参数。其中可选参数包含请求的自定义设置,它们是 -
-
method - 此处我们使用 POST 方法,表示我们正在向服务器发送数据。
-
body - 包含我们想要发送的数据。
-
headers - 它表示该数据是 JSON 数据。
现在我们在`fetch()`函数中传递请求对象以发送请求并处理服务器返回的响应,如果发生错误,则处理该错误。
<!DOCTYPE html>
<html>
<body>
<script>
// Customize setting of the request
const optional = {
// Setting POST request
method: "POST",
// Add body which contains data
body: JSON.stringify({
id: 311,
title: "Tom like Oranges",
age: 37
}),
// Setting header
headers:{"Content-type": "application/json; charset=UTF-8"}
};
// Creating request object
const newRequest = new Request("https://jsonplaceholder.typicode.com/todos", optional);
fetch(newRequest)
// Handling response
.then(response => response.json())
.then(returnData => {
console.log("Data Sent Successfully");
// Display output
document.getElementById("sendData").innerHTML = JSON.stringify(returnData);
})
// Handling error
.catch(err=>{
console.error("We get an error:", err);
});
</script>
<h2>Fetch API Example</h2>
<div>
<!-- Displaying retrieved data-->
<p id="sendData"></p>
</div>
</body>
</html>
Fetch API - Uploading Files
Fetch API 提供了一种灵活的方法来创建 HTTP 请求,该请求将文件上传到服务器。我们可以将`fetch()`函数与`FormData`对象一起使用,以在请求中发送单个或多个文件。让我们在以下示例的帮助下讨论这个概念:
Example − Uploading a Single File
在以下程序中,我们一次使用 fetch API 上传一个文件。此处我们使用`FormData`对象存储文件,然后使用`fetch()`函数将其发送到给定的 URL,其中包括 POST 请求方法和`FormData`对象。在向服务器发送请求后,我们现在使用`then()`函数来处理响应。如果我们遇到一个错误,则该错误由`catch()`函数处理。
<!DOCTYPE html>
<html>
<body>
<!-- Creating a form to upload a file-->
<form id = "myForm">
<input type="file" id="file"><br><br>
<button type="submit">Upload File</button>
</form>
<script>
document.getElementById('myForm').addEventListener('submit', function(x){
// Prevent from page refreshing
x.preventDefault();
// Select the file from the system
// Here we are going to upload one file at a time
const myFile = document.getElementById('file').files[0];
// Create a FormData to store the file
const myData = new FormData();
// Add file in the FormData
myData.append("newFiles", myFile);
// Send the file to the given URL
fetch("https://httpbin.org/post", {
// POST request with Fetch API
method: "POST",
// Adding FormData to the request
body: myData
})
// Converting the response in JSON
// using response.json() function
.then(response => response.json())
.then(finalData => {
// Handling the response
console.log("File has been uploaded successfully");
})
.catch(err=>{
// Handling the error
console.log("Error Found:", err)
});
})
</script>
</body>
</html>
Example − Uploading Multiple Files for Single Input
在以下程序中,我们将使用 fetch API 从单个输入中上传多个文件。此处我们在`<input>`标签中添加一个“multiple”属性以添加多个文件。然后我们使用`FormData`对象存储多个文件,然后使用`fetch()`函数将其发送到给定的 URL,其中包括 POST 请求方法和`FormData`对象。在向服务器发送请求后,我们现在使用`then()`函数来处理响应。如果我们遇到一个错误,则该错误由`catch()`函数处理。
<!DOCTYPE html>
<html>
<body>
<!-- Creating a form to upload a file-->
<h2> Uploading Multiple files</h2>
<form id = "myForm">
<p>Maximum number of files should be 2</p>
<input type="file" id="file" multiple><br><br>
<button type="submit">Upload File</button>
</form>
<script>
document.getElementById('myForm').addEventListener('submit', function(x){
// Prevent from page refreshing
x.preventDefault();
// Select the file from the system
// Here we are going to upload multiple files at a time
const myFile = document.getElementById('file').files[0];
// Create a FormData to store the file
const myData = new FormData();
// Add file in the FormData
myData.append("newFiles", myFile);
// Send the file to the given URL
fetch("https://httpbin.org/post", {
// POST request with Fetch API
method: "POST",
// Adding FormData to the request
body: myData
})
// Converting the response in JSON
// using response.json() function
.then(response => response.json())
.then(finalData => {
// Handling the response
console.log("Files has been uploaded successfully");
})
.catch(err=>{
// Handling the error
console.log("Error Found:", err)
});
})
</script>
</body>
</html>
Example − Uploading Multiple Files
在以下程序中,我们将使用 fetch API 上传多个文件。此处我们从具有文件类型属性的 DOM 中从系统中选择两个文件。然后我们将输入文件添加到数组中。然后我们创建一个`FormData`对象并将输入文件追加到该对象。然后我们使用`fetch()`函数将其发送到给定的 URL,其中包括 POST 请求方法和`FormData`对象。在向服务器发送请求后,我们现在使用`then()`函数来处理响应。如果我们遇到一个错误,则该错误由`catch()`函数处理。
<!DOCTYPE html>
<html>
<body>
<!-- Creating a form to upload multiple files-->
<h2> Uploading Multiple files</h2>
<input type="file">
<input type="file">
<button>Submit</button>
<script>
const myButton = document.querySelector('button');
myButton.addEventListener('click', () => {
// Get all the input files in DOM with attribute type "file":
const inputFiles = document.querySelectorAll('input[type="file"]');
// Add input files in the array
const myfiles = [];
inputFiles.forEach((inputFiles) => myfiles.push(inputFiles.files[0]));
// Creating a FormData
const myformdata = new FormData();
// Append files in the FormData object
for (const [index, file] of myfiles.entries()){
// It contained reference name, file, set file name
myformdata.append(`file${index}`, file, file.name);
}
// Upload the FormData object
fetch('https://httpbin.org/post', {
method: "POST",
body: myformdata,
})
// Handle the response
.then(response => response.json())
.then(response => console.log(response))
// Handle the error
.catch(err => console.log("Error Found:", err))
})
</script>
</body>
</html>
Fetch API - Handling Binary Data
二进制数据是以二进制格式而不是文本格式存在的数据,例如 new Uint8Array([0x43, 0x21])。它包括图像、音频、视频和不是纯文本的其他文件。我们可以在 Fetch API 中发送和接收二进制数据。在 Fetch API 中使用二进制数据时,设置正确的标头和响应类型很重要。对于二进制数据,我们使用 "Content-Type": "application/octet-stream" 和 "responseType" 属性,将其设置为 "arraybuffer" 或 "blob",表明收到了二进制数据。
让我们了解如何使用以下示例在 Fetch API 中发送和接收二进制数据。
Sending Binary Data
要发送二进制数据,我们使用 XMLHttpRequest 的 send() 方法,该方法可以使用 ArrayBuffer、Blob 或 File 对象轻松传输二进制数据。
Example
在以下程序中,我们创建一个将二进制数据发送到服务器的程序。因此,我们首先创建二进制数据,然后使用 Blob() 构造函数将二进制数据转换为 Blob。此处此构造函数需要两个参数:二进制数据和二进制数据的标头。然后我们创建一个 FormData 对象,并将 Blob 添加到 FormData 对象。然后我们使用 fetch() 函数将请求发送到服务器,然后处理服务器返回的响应,并在发生错误时处理错误。
<!DOCTYPE html>
<html>
<body>
<script>
// Binary data
var BinaryData = new Uint8Array([0x32, 0x21, 0x45, 0x67]);
// Converting binary data into Blob
var blobObj = new Blob([BinaryData], {type: 'application/octet-stream'});
// Creating FormData object
var obj = new FormData();
// Add data to the object
// Here myfile is the name of the form field
obj.append("myfile", blobObj);
// Sending data using POST request
fetch("https://jsonplaceholder.typicode.com/todos", {
// Adding POST request
method: "POST",
// Adding body which we want to send
body: obj
})
// Handling the response
.then(response =>{
if (response.ok){
console.log("Binary data send Successfully");
}
})
// Handling the error
.catch(err=>{
console.log("Found error:", err)
});
</script>
<h2>Sent Binary Data</h2>
</body>
</html>
Receiving Binary Data
在 Fetch API 中,接收二进制数据意味着在发出请求后从服务器中检索响应数据。要接收二进制数据,我们必须设置 responseType 的正确值,可能是 ArrayBuffer() 或 Blob()。
Example
在以下程序中,我们创建了一个将从服务器接收二进制数据的程序。所以我们使用 fetch() 函数从给定的 URL 获取二进制数据。在 fetch() 中我们定义了标题,告知浏览器我们正在等待二进制响应,并将响应类型设置为 arraybuffer,以便告诉浏览器您收到的响应是 ArrayBuffer。然后我们在 .then() 块中接收诺言,并检查状态是否为确定。如果状态为确定,那么借助 arrayBuffer() 函数将响应转换为 ArrayBuffer。下一个 .then() 处理返回的二进制数据,并相应地显示该数据。.catch() 函数处理如果发生错误。
<!DOCTYPE html>
<html>
<body>
<script>
// Receiving data using GET request
fetch("https://jsonplaceholder.typicode.com/todos", {
// Adding Get request
method: "GET",
// Setting headers
headers: {
'Content-Type': 'application/octet-stream',
},
// Setting response type to arraybuffer
responseType: "arraybuffer"
})
// Handling the received binary data
.then(response =>{
if (response.ok){
return response.arrayBuffer();
}
console.log("Binary data send Successfully");
})
.then(arraybuffer => console.log("Binary data received Successfully"))
// Handling the error
.catch(err=>{
console.log("Found error:", err)
});
</script>
<h2>Binary Data Example</h2>
</body>
</html>
Fetch API - Status Codes
Fetch API 提供了一个用于查找请求状态的特殊属性,该属性的名称为状态属性。它是 Response 接口的一个只读属性,它返回由给定请求的服务器发送的响应的 HTTP 状态码。例如,404 - 找不到资源,200 - 成功,400 - 错误的请求等。它得到了所有现代网络浏览器的支持。
Successful
成功的状态码是在请求成功完成后服务器将返回的状态码。一些常用的成功状态码及其含义如下:
Status |
Message |
Description |
200 |
OK |
如果请求可以。 |
201 |
Created |
当请求完成并创建了一个新资源。 |
202 |
Accepted |
当请求被服务器接受。 |
204 |
No Content |
当响应主体中没有数据。 |
205 |
Reset Content |
对于其他输入,浏览器会清除用于事务的表单。 |
206 |
Partial Content |
当服务器返回指定大小的部分数据。 |
Redirection
重定向状态代码是表征重定向响应状态的状态代码。常用重定向状态代码及其说明如下 −
Status |
Message |
Description |
300 |
Multiple Choices |
它用于表征链接列表。因此,用户可以选择任何一个链接并前往该位置。它只允许五个位置。 |
301 |
Moved Permanently |
当请求的页面移动到新 URL。 |
302 |
Found |
当请求的页面在不同的 URL 中找到。 |
304 |
Not modified |
URL is not modified. |
Client Error
客户端错误状态代码表征在请求期间客户端发生的错误。或者可以说,它们通知客户端,由于错误,请求未成功。常用客户端错误状态代码及其说明如下 −
Status |
Message |
Description |
400 |
Bad Request |
服务器无法完成请求,因为请求格式错误或者具有无效语法。 |
401 |
Unauthorised |
请求需要身份验证,并且用户未提供有效凭证。 |
403 |
Forbidden |
服务器了解该请求,但无法完成它。 |
404 |
Not Found |
找不到请求的页面。 |
405 |
Method Not Allowed |
通过该请求进行请求的方法不受该页面支持。 |
406 |
Not Acceptable |
客户无法接受服务器生成的响应。 |
408 |
Request Timeout |
Server timeout |
409 |
Conflict |
请求由于请求中的冲突而未完成。 |
410 |
Gone |
请求的页面不可用。 |
417 |
Exception Failed |
服务器不匹配 Expect 请求头字段的要求。 |
Server Error
服务器错误状态代码表示请求期间服务器端发生的错误。或者我们可以说它们通知客户端由于服务器出现错误,请求未成功。以下是常用的一些服务器错误状态代码及其说明 −
Status |
Message |
Description |
500 |
Internal Server Error |
当服务器在处理请求时遇到错误。 |
501 |
Not Implemented |
当服务器不识别请求方法或无法满足请求时。 |
502 |
Bad Gateway |
当服务器作为网关并从另一台服务器(上游)恢复无效响应时。 |
503 |
Service Unavailable |
当服务器不可用或关闭时。 |
504 |
Gateway Timeout |
当服务器作为网关且未及时从另一台服务器(上游)收到响应时。 |
505 |
HTTP Version Not Supported |
当服务器不支持 HTTP 协议版本时。 |
511 |
Network Authentication Required |
当客户端需要验证以获取对网络的访问权限时。 |
Example 1: Finding status code using fetch() function
在以下程序中,我们找到当前请求的状态代码。为此,我们从给定的 URL 获取数据。如果服务器返回的响应为 OK,则显示状态代码。如果不是,则显示请求失败状态。如果出现错误,则此代码使用 catch() 函数来处理错误。
<!DOCTYPE html>
<html>
<body>
<script>
fetch("https://jsonplaceholder.typicode.com/todos")
.then(response=>{
if (response.ok){
const mystatus = response.status;
// Display output in HTML page
document.getElementById("sendData").innerHTML = JSON.stringify(mystatus);
}else{
console.log("Request Fail:", mystatus);
}
})
// Handling error
.catch(err =>{
console.log("Error is:", err)
});
</script>
<h2>Status code of request</h2>
<div>
<p>Status of the current request is </p>
<!-- Displaying data-->
<p id = "sendData"></p>
</div>
</body>
</html>
Example 2: Finding status code using fetch() function with async/await
在以下程序中,我们找到当前请求的状态代码。为此,我们创建了一个异步函数。在此函数中,我们使用 fetch() 函数从给定的 URL 提取数据。如果服务器返回的响应为 OK,则在控制台日志中显示状态代码。如果不是,则显示请求失败状态。如果我们遇到错误,此代码将使用 catch() 函数来处理该错误。
<!DOCTYPE html>
<html>
<head>
<title>Fetch API Example</title>
</head>
<body>
<h1>Example of Fetch API</h1>
<script>
async function getStatus() {
try {
const myResponse = await fetch("https://jsonplaceholder.typicode.com/todos");
// Finding the status of the request
console.log("Status of the request:", myResponse.status);
console.log(myResponse);
} catch (err) {
console.log("Error is:", err);
}
}
getStatus();
</script>
</body>
</html>
Stream API - Basics
借助 JavaScript 编程语言,流 API 允许开发人员访问通过网络接收的数据流,并根据他们的需求逐位处理它们。流是我们希望通过网络分批接收到并逐位处理的小批量数据序列。
在流式传输之前,如果我们想要处理视频、音频或文本文件,我们需要从网络下载该完整文件并等待将其反序列化为指定格式,然后处理已下载的完整文件。
在引入流之后,整个工作文化发生了变化,现在我们可以使用 JavaScript 在客户端接收数据之后立即开始逐位处理数据,而无需创建任何额外的缓冲区或 Blob。使用流,我们可以执行各种任务,如查找流的开始和结束,或者可以将流串联起来,或者可以轻松处理错误,可以取消流,还可以执行更多操作。
流式传输可用于创建真实世界的应用程序,如 Netflix、亚马逊 Prime 视频、Zee5、Voot、YouTube 等视频流应用程序。这样,用户可以轻松地在网上观看电影、电视剧等,而无需下载它们。流 API 提供各种功能,如 ReadableStream、分流、WritableStream、管道链、反压、内部队列和排队策略。让我们逐一详细讨论它们。
Readable Stream
可读流允许你使用 ReadableStream 对象在 JavaScript 中从源读取数据/块。块是要由读取器按顺序读取的小块数据。它可以是单个位,也可以是类型化数组之类的较大内容。要读取可读流,API 提供一个读取器。它从流中读取块,然后处理块的数据。一次只能有一个读取器读取流,不允许其他读者读取该流。
Writable Stream
可写流允许你使用 Writable Stream 对象在 JavaScript 中写入数据。数据由写入器写入流。写入器以块的形式(一次一个块)写入数据。当写入器被创建并开始向流写入数据时,该流就会被锁定,并且不允许任何其他写入器访问该流,并使用内部队列来跟踪写入器写入的块。
Teeing
分流是一个将流拆分为流的两个相同副本的过程,以便两个独立的读者可以同时读取该流。我们可以借助 ReableStream.tee() 方法实现分流。该方法返回一个包含指定流的两个相同副本的数组,并且可以由两个读取器读取。
Pipe Chains
管道链是一个将多个流连接在一起以创建数据处理流的过程。在流 API 中,我们可以借助管道链结构将一个流管道到另一个流中。管道链的起点称为原始源,管道链的最后一个点称为最终接收器。
管道流,我们可以使用以下方法:
ReadableStream.pipeThrough() − 该方法用于通过转换流对当前流进行管道化。转换流包含一对可读和可写流。
ReadableStream.pipeTo() − 该方法用于将当前 ReadableStream 管道到指定的 WritableStream,并将返回一个 promise,该 promise 在管道处理成功完成或因某种错误而被拒绝时解析。
Backpressure
反压是流 API 中的一个特殊概念。在这个过程中,单个流或管道链控制读/写速度。假设我们有一个流,此流很忙,无法接受新的数据块,因此会通过链发送一条反向消息,告诉转换流减慢块的传递速度,以便我们可以避免瓶颈。
我们可以在 ReadableStream 中使用反压,因此我们需要在 ReadableStreamDefaultContriller.desiredSize 属性的帮助下找到消费者所需的数据块大小。如果数据块大小很小,则 ReadableStream 可以指示它的底层来源,以停止发送更多数据,并将反压与流链一起发送回去。
当消费者再次想要接收的数据时,我们使用 pull 方法告诉底层来源将数据发送到流。
Stream API - Readable Streams
在 Stream API 中,可读流是我们可以顺序且异步地从中读取数据的数据源。它是从底层来源获取数据的一种标准化方式。底层来源是网络上存在的资源。它们有以下两种类型:
Push source − 在这种情况下,当你访问数据时,数据会推送到你那里。你可以控制流,比如何时开始或何时暂停,甚至何时终止当前流。例如,视频游戏流。
Pull source − 在这种情况下,你需要明确地向它们请求数据。例如,使用 Fetch 或 XHR 调用访问文件。
在可读流中,数据以小块的形式存在,因此一次一个块地顺序读取。一个块可以是一个字节,也可以是更大的大小。因此,数据块的大小在流中可以不同。现在让我们了解可读流如何工作。
Working of Readable Stream
可读流的工作非常直接。在可读流中,数据块被放置在队列中。这意味着这些块正在等待读取队列。这里我们有另一个队列,这是一个内部队列,用于跟踪未读块。这些块由读者读取。它一次处理一个块的数据,并允许你对数据执行操作。一个读者一次只能读取一个流。当读者开始读取流时,该流就被锁定,该读者表示不允许其他读者读取该流。如果你希望另一个读者读取该流,则必须终止第一个读者或可以创建一个分流流。此外,每个读者都有自己的控制器,它允许你控制流,例如开始、关闭或暂停。
它还有一个使用者,负责处理从可读流接收的数据并对其进行处理,并且能够对其进行操作。
Readable Stream Interfaces
Stream API 支持三种类型的可读流接口:
-
ReableStream Interface
-
ReableStreamDefaultReader Interface
-
ReadableStreamDefaultController Interface
Syntax
const newRead = new ReadableStream()
Or
const newRead = new ReadableStream(UnderlyingSource)
Or
const newRead = new ReadableStream(UnderlyingSource, QueuingStrategy)
以下是 ReadableStream() 构造函数的可选参数:
UnderlyingSource − 这个对象提供了各种方法和属性,它们定义了流实例的行为。这些方法是:start()、pull() 和 cancel(),而这些属性是:type 和 autoAllocateChunkSize。
QueuingStrategy −此对象用于为给定的流定义排队策略。它采用两个参数:highWaterMark 和 size(chunk)。
Instance Properties
ReadableStream 接口提供的属性为只读属性。因此 ReadableStream 提供的属性为:
Sr.No. |
Property & Description |
1 |
ReadableStream.locked 此属性用于检查可读流是否已被锁定到某个读者。 |
Methods
以下为 ReadableStream 接口常用的方法:
Sr.No. |
Method & Description |
1 |
ReadableStream.cancel() 此方法返回一个 Promise,当该流已取消时该 Promise 会完成。 |
2 |
ReadableStream.getReader() 此方法用于创建一个读者并将其锁定到该流。在释放此读者之前,不允许有其他读者。 |
3 |
ReadableStream.pipeThrough() 此方法用于创建一个可链式的方式,以将当前流通过一个转换流进行传输。 |
4 |
ReadableStream.pipeTo() 此方法用于将当前 ReadableStream 传输到给定的 WriteableStream。如果传输过程成功完成,则它将返回一个 Promise;如果由于某个错误而导致传输失败,则它将对其进行拒绝。 |
5 |
ReadableStream.tee() 此方法用于获取一个包含两个结果分支的双元素数组,这两个分支作为新的 ReadableStream 对象。 |
ReadableStreamDefaultReader Interface
ReadableStreamDefaultReader 接口用于表示一个默认读者,此默认读者会从网络中读取流数据。它也可以从 ReadableStream 读取。
Constructor
为了创建一个 readableStreamDefualtReader 对象,ReadableStreamDefaultReader 接口提供了一个 ReadableStreamDefaultReader() 构造函数。
Syntax
const newRead = new ReadableStreamDefaultReader(myStream)
此构造函数仅包含一个参数,它便是 myStream。它将读取 ReadableStream。
Instance Properties
ReadableStreamDefaultReader 接口提供的属性为只读属性。因此 ReadableStreamDefaultReader 提供的属性为:
Sr.No. |
Property & Description |
1 |
ReadableStreamDefaultReader.closed 此属性返回一个 Promise,当该流因某个错误而关闭或被拒绝时,该 Promise 会完成。这允许你编写一个程序,该程序将在流处理过程结束时做出响应。 |
Methods
以下为 ReadableStream 接口常用的方法:
Sr.No. |
Method & Description |
1 |
ReadableStreamDefaultReader.cancel() 此方法返回一个 Promise,当该流已取消时该 Promise 会完成。 |
2 |
ReadableStreamDefaultReader.read() 此方法返回一个 Promise,该 Promise 将提供对流队列中的下一个区块或数据块的访问。 |
3 |
ReadableStreamDefaultReader.releaseLock() 此方法用于取消该流上读者的锁定。 |
ReadableStreamDefaultController Interface
ReadableStreamDefaultController 接口表示一个控制器,它允许我们控制 ReadableStream 状态或内部队列。它不提供任何控制器,并且在构造 ReadableStream 时会自动创建该实例。
Instance Properties
Sr.No. |
Property & Description |
1 |
ReadableStreamDefaultController.desiredSize 此属性用于查找填充流内部队列所需的容量大小。 |
ReadableStreamDefaultController 接口提供的属性为只读属性。因此 ReadableStreamDefaultController 提供的属性为:
Methods
以下是 ReadableStreamDefaultController 接口常用的方式 -
Sr.No. |
Property & Description |
1 |
ReadableStreamDefaultController.close() 此方法用于关闭相关流。 |
2 |
ReadableStreamDefaultController.enqueue() 此方法用于将指定数据块或片段放入相关流中。 |
3 |
ReadableStreamDefaultController.error() 此方法将导致任何未来的交互与相关流到错误。 |
Example - Creating ReadableStream
在以下程序中,我们将使用 ReadableStream 构造函数创建一个自定义可读流。因此,我们首先创建了一个以块为单位生成数据的函数。然后,我们使用包含 start() 函数的 ReadableStream() 构造函数创建一个可读流。此 start() 函数使用 pData() 递归函数,该函数通过控制器将 myData() 功能中的数据推给使用者,其中每个推送操作之间设置 1 秒的超时。现在,我们使用 getReader() 函数创建读取器以使用流中的数据。然后,我们创建一个 readMyData() 函数,以在读者的帮助下从流中递归读取数据。流结束时,完成标志设置为 true,我们退出递归循环。
<!DOCTYPE html>
<html>
<body>
<script>
// Function that produces data for the stream
function* myData() {
yield 'pink';
yield 'blue';
yield 'yellow';
yield 'green';
}
// Create a readable stream using ReadableStream() function
const readStream = new ReadableStream({
start(controller) {
const data = myData();
// Adding data to the stream
function pData() {
const { done, value } = data.next();
if (done) {
// Close the stream if no more data is available
controller.close();
return;
}
// Pushing the data to the consumer
controller.enqueue(value);
// Continue pushing data after 1 sec
setTimeout(pData, 1000);
}
// Calling the pData function to start pushing data
pData();
}
});
// Create a reader for the readable stream
const myreader = readStream.getReader();
function readMyData() {
myreader.read().then(({ done, value }) => {
if (done) {
// Stream is closed
console.log('Stream is closed');
return;
}
// Processing the received data
console.log('Received data:', value);
// Continue reading the data
readMyData();
});
}
// Calling readMyData() function to start
// reading data from the readable stream
readMyData();
</script>
</body>
</html>
Stream API - Writeable Streams
可写流是可以写入数据的流。它们通常在 JavaScript 中由 WritableStrem 对象表示。它在底层接收器上创建了一个抽象。底层接收器是原始数据被写入的较低级别的输入/输出接收器。
在可写流中,一个写入器写入数据。它一次写入一个块,其中块是数据的一部分。此外,您可以使用任何代码生成要写入的块,并且写入器和相关代码一起称为生产者。在单个流上,只允许一个写入器写入数据。在那个时候,流对那个指定的写入器被锁定,不允许其他写入器写入。如果您希望另一个写入器写入,则必须在该另一个写入器被允许写入之后终止第一个写入器。每个写入器都有自己的控制器来控制流。
此外,可写流具有与可读流一样的内部队列。它还跟踪已被写入但未由底层接收器处理的块。
WritableStream Interfaces
Stream API 支持三种类型的可写流接口 −
-
WritableStream Interface
-
WritableStreamDefaultWriter Interface
-
WritableStreamDefaultController Interface
Syntax
const newWrite = new WritableStream(UnderlyingSink)
Or
const newWrite = new WritableStream(UnderlyingSink, QueuingStrategy)
WritableStream() 构造函数具有以下可选参数 -
UnderlyingSink - 该对象提供各种特性和信息,显示写入流实例的行为。它获取四个参数:start(controller)、write(chunk, controller)、close(controller) 和 abort(reason)。
QueuingStrategy - 该对象用于定义写入流的排队策略。它获取两个参数:highWaterMark 和 size(chunk)。
Instance Properties
WritableStream 接口提供的属性为只读属性。因此 WritableStream 提供的属性如下:
Sr.No. |
Property & Description |
1 |
WritableStream.locked 该属性用于检查 WritableStream 是否已锁定到编写器。 |
Methods
以下是 WritableStream 接口中常用的方法:
Sr.No. |
Property & Description |
1 |
WritableStream.close() 该方法用于关闭流。 |
2 |
WritableStream.abort() 该方法用于终止流。 |
3 |
WritableStream.getWriter() 该方法用于获取 WriteableStreamDefaultWriter 的新对象,并将流锁定为此实例。当流被锁定时,其他编写器不能获取流,直至当前对象被释放。 |
Constructor
要创建一个 WritableStreamDefaultWriter 对象,WritableStreamDefaultWriter 接口提供了一个 WritableStreamDefaultWriter() 构造函数。
Syntax
const newWrite = new WritableStreamDefaultWriter(myStream)
此构造函数仅包含一个参数,它便是 myStream。它将读取 ReadableStream。
Instance Properties
WritableStreamDefaultWriter 接口提供的属性为只读属性。因此 WritableStreamDefaultWriter 提供的属性如下:
Sr.No. |
Property & Description |
1 |
WritableStreamDefaultWriter.closed 该属性返回一个承诺,如果流因某些错误而关闭或拒绝,则该承诺将解决。它允许你创建一个在流进程结束时响应的程序。 |
2 |
WritableStreamDefaultWriter.desiredSize 该属性用于获取将满足流内部队列的所需大小。 |
3 |
WritableStreamDefaultWriter.ready 该属性返回一个承诺,当流内部队列的所需大小从负数转变为正数时,该承诺将解决。 |
Methods
以下是 WritableStreamDefaultWriter 接口中常用的方法:
Sr.No. |
Method & Description |
1 |
WritableStreamDefaultWriter.abort() 该方法用于终止流。 |
2 |
WritableStreamDefaultWriter.close() 此方法用于关闭可写流。 |
3 |
WritableStreamDefaultWriter.releaseLock() 此方法用于移除写入器对相应流的锁。 |
4 |
WritableStreamDefaultWriter.write() 此方法用于将传递的数据块写入 WritableStream 及其底层接收器。它将返回一个 Promise,该 Promise 解决为确定写入操作是失败还是成功。 |
WritableStreamDefaultController Interface
WritableStreamDefaultController 接口表示一个控制器,允许我们控制 WritableStream 状态。它不提供任何控制器,并且该实例在构造 WritableStream 时自动创建。
Instance Properties
WritableStreamDefaultController 接口提供的属性为只读属性。因此,WritableStreamDefaultController 提供的属性为 −
Sr.No. |
Property & Description |
1 |
WritableStreamDefaultController.signal 此属性将返回与指定控制器相关的 AbortSignal。 |
Methods
以下是 WritableStreamDefaultController 接口常用的方法 −
Sr.No. |
Method & Description |
1 |
WritableStreamDefaultController.error() 此方法会导致与相关写入流的任何未来交互都会出错。 |
Example - Creating Writable Stream
在以下程序中,我们创建了一个自定义可写流。因此,要创建一个可写流流 API,请提供具有 write()、cancel() 和 abort() 函数的 WritableStream() 构造函数。write() 函数用于记录接收到的块,cancel() 函数用于处理流被取消时,abort() 函数用于处理流被中止时。现在,我们使用 getWriter() 方法创建了一个写入器,以便在流中写入数据。因此,写入器将数据写入块中,并在完成写入操作后关闭流。
<!DOCTYPE html>
<html>
<body>
<script>
// Creating a writable stream
const writStream = new WritableStream({
// processing the received chunks
write(chunk) {
console.log('Received chunk:', chunk);
},
// Closing the stream
close(){
console.log('Stream is closed');
},
// Handling the aborting stream
abort(reason){
console.log('Stream is aborted:', reason);
}
});
// Create a writer to write in the stream
const myWriter = writStream.getWriter();
// Writing in the stream
myWriter.write('Orange');
myWriter.write('Blue');
myWriter.write('Pink');
myWriter.write('Red');
// Close the stream
myWriter.close();
</script>
</body>
</html>
Stream API - Transform Streams
在 Stream API 中,转换流用于实现管线概念。管线是一个过程,其中多个流相互连接。原始源是管线的起始点,而最终汇是管线的结束点。
TransformStream Interface
流 API 支持两种类型的转换流接口 -
-
TransformStream Interface
-
TransformStreamDefaultController
Constructor
为了创建一个转换流对象,TransformStream 接口提供了一个 TransformStream() 构造函数。此对象表示流对,即用于可写面的 WritableStream 和用于可读面的 ReadableStream。
Syntax
const newTrans = new TransformStream()
Or
const newTrans = new TransformStream(mtransform)
Or
const newTrans = new TransformStream(mtransform, writableStrategy)
Or
const newTrans = new TransformStream(mtransform, writableStrategy, readableStrategy)
以下是 TransformStream() 构造函数的可选参数 -
-
mtransform - 此对象表示转换器。start(controller)、transform(chunk, controller) 和 flush(controller) 是转换器对象包含的方法。其中控制器是 TransformStreamDefaultController 的实例。
-
writableStrategy - 此对象用于定义写入流的排队策略。它采用两个参数:highWaterMark 和 size(chunk)。
-
readableStrategy - 此对象用于定义读取流的排队策略。它采用两个参数:highWaterMark 和 size(chunk)。
Instance Properties
TransformStream 接口提供的属性是只读属性。因此,TransformStream 提供的属性 -
Sr.No. |
Property & Description |
1 |
TransformStream.readable 此属性返回 TransformStream 的可读端。 |
2 |
TransformStream.writable 此属性返回 TransformStream 的可写端。 |
TransformStreamDefaultController Interface
TransformStreamDefaultController 接口提供了各种方法来处理 ReadableStream 和 WritableStream。当我们创建一个 TransformStream 时,将自动创建 TransformStreamDefaultController。因此,不需要任何单独的构造函数。
Instance Properties
TransformStreamDefaultController 接口提供的属性是只读属性。因此,TransformStreamDefaultController 提供的属性 -
Sr.No. |
Property & Description |
1 |
TransformStreamDefaultController.desiredSize 此属性返回一个大小,该大小将填充流内部队列的可读部分。 |
Methods
以下为 TransformStreamDefaultController 接口常用的方法−
Sr.No. |
Method & Description |
1 |
TransformStreamDefaultController.enqueue() 此方法用于在给定流的可读部分上排队放置一块数据。 |
2 |
TransformStreamDefaultController.error() 此方法用于在流的可读部分和可写部分上查找错误。 |
3 |
TransformStreamDefaultController.terminate() 此方法用于关闭可读部分和转换流的可写部分的错误。 |
Example - Creating Transform Stream
在以下程序中,我们创建一个自定义转换流。因此,要创建一个转换流,我们使用 TransformStream() 构造函数,并使用 transform()、flush()、start() 和 cancel() 函数。 transform() 函数实现接收到的块,然后将它们转换为大写,然后使用 enqueue() 方法排队放置数据。 flush() 方法用于处理流结束,start() 方法用于处理初始化,cancel() 方法用于处理取消。现在,我们使用 getWriter() 方法从转换流获取编写器来读取流的数据。然后,我们使用 getReader() 函数为转换流获取读取器。它在 myread() 函数的帮助下从流读取和处理转换后的数据。
<!DOCTYPE html>
<html>
<body>
<script>
// Create a transform stream using TransformStream() constructor
const newTransform = new TransformStream({
transform(chunk, controller) {
// Processing the received chunk in uppercase
const tData = chunk.toString().toUpperCase();
// Enqueue the transformed data and passed it to the downstream
controller.enqueue(tData);
},
// Handling the finalized data, if required
flush(controller) {
console.log('Stream is flushing');
},
// Performing the initialization, if required
start(controller) {
console.log('Stream is started');
},
// Handling the stream if it is cancelled
cancel(reason) {
console.log('Stream got canceled:', reason);
}
});
// Creating a writer for the transform stream
const twriter = newTransform.writable.getWriter();
// Writing the data into the transform stream
twriter.write('pink');
twriter.write('green');
twriter.write('blue');
// Closing the stream
twriter.close();
// Creating a reader for the transform stream
const treader = newTransform.readable.getReader();
// Read and process data from the transform stream
function myread(){
treader.read().then(({ done, value }) => {
if (done) {
console.log('Stream is ended');
return;
}
// Processing the received transformed data
console.log(value);
// Continue reading data from the stream
myread();
});
}
// Calling the myread() to start reading from the transform stream
myread();
</script>
</body>
</html>
Stream API - Request Object
请求对象用于从服务器获取资源。请求对象是通过使用 Resquest 接口提供的 Resquest() 构造函数创建。因此,当新请求对象创建时,我们被允许向 Request 对象的主体传递一个 ReadableStream,此类请求被称为流式请求。然后将此请求对象传递给 fetch() 函数以获取资源。
Syntax
const myobject = new Request(URL, {
method: 'POST',
body: Stream,
headers: {'Content-Type'},
duplex: 'half',
});
此处,Request() 构造函数包含以下参数:
-
URL - 资源的地址。
-
method - 它表示 HTTP 请求方式,例如 GET、POST 等。
-
body - 包含 ReadableStream 对象。
-
headers - 包含适合于主体的大小写。
-
duplex −设为一半才能形成双工流。
Example
在以下程序中,我们创建一个流式请求。所以为了这个,我们首先借助 can start() 函数和 ReadableStream() 构造函数创建了一个可读流,它实现了 ReadableStream 逻辑和其他操作。然后我们借助 Request() 构造函数创建一个请求对象,以及选项: method 选项包含 POST 请求来发送请求, body 选项包含流, headers 选项包含适当的头部,并将 duplex 选项设为一半以使其成为双工流。现在在创建了一个请求对象后,我们把该对象传递给取用() 函数来进行请求,该函数使用 then() 处理响应,并使用 catch() 函数处理错误(如果出现)。在这里,你可以使用 https://exampleApi.com/, 代替一个有效的 API/URL 来以块的形式发送/接收数据。
<script>
// Create a readable stream using the ReadableStream constructor()
const readStream = new ReadableStream({
start(controller) {
// Here implement your ReadableStream
// Also with the help of controller, you can enqueue data and
// signal the end of the stream
},
});
// Create a request objecct using Request() constructor
const request = new Request('https://exampleApi.com/', {
// Set the method
method: 'POST',
// Passing the stream to the body of the request
body: stream,
// Setting suitable header
headers: {'Content-Type': 'application/octet-stream'},
duplex: 'half'
});
// After creating a request object pass the object
// to fetch() function make a request or perform operations
fetch(request)
.then(response => {
// Handling the response
})
.catch(error => {
// Handling any errors if occur
});
</script>
Restrictions
流式请求是一个新功能,所以它有一些限制 −
Half duplex −为了执行流式请求,我们必须将 duplex 选项设为一半。如果你在流式请求中没有设置此选项,那么你会收到一条错误信息。此选项说明该请求主体是一个双工流,其中双工流是一个同时接收数据(可写)和发送数据(可读)的流。
Required CORS and trigger a preflight −正如我们所知,流式请求在请求主体中包含一个流,但没有“Content-Length”头部。所以对于这种类型的请求,必须进行 CORS 并且它们总会触发一个预检。而且,不允许无 CORS 流式请求。
Does not work on HTTP/1.x −如果连接是 HTTP/1.x,那么它将根据 HTTP/1.x 规则拒绝取用。根据 HTTP/1.x 规则,请求和响应主体需要发送一个 Content-Length 头部。这样,另一方就可以记录收到的数据量,或更改格式以使用分块编码。分块编码很常见,但对于请求而言,它非常少见。
Server-side incompatibility −某些服务器不支持流式请求。所以始终只使用支持流式请求的那些服务器,例如 NodeJS 等。
Stream API - Response Body
在 Stream API 中,body 是 Response 接口的属性。它用于获取 ReableStream 的正文内容。它是一个只读属性。响应正文不会以一个正文发送,而是分成小块发送,客户端在接收到数据后立即开始处理。它不必等到响应完成后。
Example
在以下程序中,我们将看到如何在 Stream API 中使用 Response Body。因此,为此,我们使用 fetch() 向给定的 URL 发送 GET 请求。如果响应成功,则使用 response.body.getReader() 将响应正文获取为“ReadableStream”。然后,我们定义一个 readMyStream() 函数来读取从流中接收的数据块。如果发生任何错误,则将由 catch() 函数成功处理。
<script>
// fetch() function to send GET request
fetch('http://example.com/')
.then(response => {
if (response.ok) {
// Using body property we get the ReadableStream
const myReader = response.body.getReader();
// Using this function we read the chunks
function readMyStream() {
return myReader.read().then(({ done, value }) => {
if (done) {
// Stream is completed
return;
}
// Process the data from the chunks
const receivedData = new TextDecoder().decode(value);
console.log(receivedData);
// Continue reading
return readMyStream();
});
}
return readMyStream();
}
})
.catch(error => {
// Handling error
console.log('Found Error:', error);
});
</script>
Stream API - Error Handling
在使用流式传输 API 时,有时会由于网络中断、服务器端问题、数据传输等原因而返回错误。因此,为了处理这些错误,每个 API 都在流式传输过程中使用各自的错误处理机制。这使得应用程序更加健壮且更有韧性。因此,常用的错误处理做法包括以下几个方面:
Error Event Listeners − 几乎所有流式传输 API 都支持错误事件侦听器。当发生错误时,错误事件侦听器就会发挥作用并让你能够恰当地处理该错误。它可以与 WebSocket、Fetch API 或 ReadableStream 等合适的对象一起使用。
Try-Catch Block − 在使用特定类型流中的同步代码时,您可以使用 try-catch 块来处理错误。
Promises and Async/Await − 在将 Promise 或 Async/Await 与流 API 结合使用时,您可以使用 catch 块来处理流传输过程中发生的错误。
Backoff and Retry Method − 如果您的错误不是临时的,那么可以使用退避和重试方法。在此方法中,应用程序在短时间内等待数据,如果在该时间段内未收到数据,则从失败的操作中重试。
User-friendly error message − 如果发生错误,则向最终用户提供简单且用户友好的错误消息,以避免显示可能使用户困惑的技术细节并能够避免安全风险。
Data Validation − 始终确保来自流 API 的传入数据经过正确验证和清理,以避免数据格式错误或意外数据倾向于处理问题。