当前位置: 首页 > news >正文

JavaScript 第13章:Ajax 与异步请求

在Web开发中,异步请求是一种非常重要的技术,它可以让网页在不重新加载的情况下与服务器交互。本章将介绍两种常用的异步请求技术:XMLHttpRequestFetch API,以及它们如何用于处理JSON数据交换,并通过一个实战案例——获取天气信息来加深理解。

1. XMLHttpRequest

XMLHttpRequest 是最早的异步请求实现之一,它允许JavaScript代码从服务器请求数据而不必刷新整个页面。虽然名字中包含“XML”,但它可以用来请求任何类型的数据,包括HTML、JSON等。

示例代码:
function loadDoc() {var xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() {if (this.readyState == 4 && this.status == 200) {console.log(this.responseText);}};xhttp.open("GET", "https://api.example.com/data", true);xhttp.send();
}

这里创建了一个新的XMLHttpRequest对象,然后设置了一个事件处理器来处理onreadystatechange事件。当请求完成并且状态码为200(表示成功)时,会打印出从服务器返回的文本数据。

2. Fetch API

随着Web的发展,XMLHttpRequest被认为有些过时了,Fetch API提供了一个更现代化的方法来处理HTTP请求。它返回的是Promise,可以更好地集成到现代的JavaScript代码中。

示例代码:
fetch('https://api.example.com/data').then(response => response.json()) // 转换响应体为json.then(data => console.log(data)) // 打印json数据.catch((error) => {console.error('Error:', error);});

这个例子展示了如何使用fetch来获取数据并处理JSON响应。如果请求过程中出现错误,catch块会捕获并记录错误。

3. JSON 数据交换

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。在异步请求中,服务器通常返回JSON格式的数据,然后客户端使用JavaScript来处理这些数据。

4. 实战案例:获取天气信息

假设我们要创建一个简单的应用,展示用户的当前位置的天气信息。我们可以使用Geolocation API来获取用户的地理位置,然后用这个位置信息向天气API发起请求。

示例代码:
if (navigator.geolocation) {navigator.geolocation.getCurrentPosition(position => {const latitude = position.coords.latitude;const longitude = position.coords.longitude;fetch(`https://api.weatherapi.com/v1/current.json?key=YOUR_API_KEY&q=${latitude},${longitude}`).then(response => response.json()).then(data => console.log(data)).catch(error => console.error(error));}, error => console.error(error));
} else {console.error("Geolocation is not supported by this browser.");
}

这段代码首先检查浏览器是否支持Geolocation API,然后获取用户的位置。接着,使用获取到的经纬度向一个天气API发送请求来获取天气信息。请注意,在实际应用中,你需要替换YOUR_API_KEY为你从天气服务提供商那里获得的有效API密钥。

我们可以在上面的基础上进一步扩展一些细节和最佳实践,确保你能够有效地使用异步请求来构建健壮的应用程序。

进阶主题:

错误处理

在进行网络请求时,错误处理是必不可少的一部分。除了上面提到的使用catch来捕获错误之外,还应该考虑以下情况:

  • 超时:网络请求可能会因为各种原因而长时间没有响应,这时你可以设置一个超时时间来避免应用程序挂起。
  • HTTP错误状态:即使请求成功发送到了服务器,也可能因为权限问题或其他原因而返回非200的状态码。你应该检查response.okresponse.status来判断请求是否真正成功。
取消请求

有时你可能需要在请求完成之前取消它,比如用户导航离开页面或者组件卸载时。你可以使用AbortController来实现这一点:

const controller = new AbortController();
const signal = controller.signal;fetch(url, { signal }).then(response => {if (!response.ok) {throw new Error(`Network response was not ok: ${response.statusText}`);}return response.json();}).then(data => console.log(data)).catch(error => console.error(error));// 取消请求
controller.abort();
缓存策略

为了提高性能,你可以使用不同的缓存策略来存储API响应结果。例如,使用Service Worker可以实现离线访问。

使用头部

当你需要发送额外的信息给服务器时,例如认证信息或者告诉服务器你期望接收的响应类型,可以通过设置请求头来实现:

fetch(url, {method: 'POST',headers: {'Content-Type': 'application/json','Authorization': 'Bearer your-access-token'},body: JSON.stringify({ key: 'value' })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));

性能优化

  • 减少请求数量:合并请求,减少HTTP往返次数。
  • 并发请求:同时发起多个请求以减少总等待时间,但要注意不要过度消耗资源。
  • 预加载:提前加载可能需要的数据以改善用户体验。

实战案例:天气信息展示

让我们进一步完善天气信息获取的功能,使其不仅仅是一个控制台输出,而是在网页上动态显示出来:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Weather App</title>
</head>
<body>
<h1>Current Weather</h1>
<div id="weather"></div><script>
document.addEventListener('DOMContentLoaded', () => {if (navigator.geolocation) {navigator.geolocation.getCurrentPosition(position => {const latitude = position.coords.latitude;const longitude = position.coords.longitude;fetchWeather(latitude, longitude);}, error => console.error(error));} else {document.getElementById('weather').textContent = 'Geolocation is not supported.';}
});function fetchWeather(lat, lon) {const apiKey = 'YOUR_API_KEY';const url = `https://api.weatherapi.com/v1/current.json?key=${apiKey}&q=${lat},${lon}`;fetch(url).then(response => response.json()).then(data => displayWeather(data)).catch(error => console.error(error));
}function displayWeather(data) {const weatherDiv = document.getElementById('weather');weatherDiv.innerHTML = `<p><strong>Location:</strong> ${data.location.name}</p><p><strong>Temperature:</strong> ${data.current.temp_c}°C</p><p><strong>Condition:</strong> ${data.current.condition.text}</p>`;
}
</script>
</body>
</html>

这段代码定义了一个简单的HTML页面,其中包含了一个<div>元素来显示天气信息。当DOM内容加载完成后,尝试获取用户的地理位置,并调用fetchWeather函数来获取天气数据。最后,使用displayWeather函数来更新页面上的内容。

通过这些步骤,你应该能够更好地理解和应用异步请求技术来增强你的Web应用程序功能。

好的,让我们继续深入探讨有关异步请求的一些高级主题,并且提供更多的实践技巧。

高级主题

复杂请求 - POST 请求

有时候我们需要向服务器发送数据,这时候就需要用到POST请求。POST请求通常用于创建新资源或更新现有资源。

fetch('/some-endpoint', {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify({key: 'value'})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));

在这个例子中,我们发送了一个包含JSON数据的POST请求,并且设置了适当的Content-Type头来告知服务器我们将发送JSON数据。

多个请求的处理

如果你的应用程序需要同时处理多个异步请求,你可以使用Promise.all来等待所有请求都完成。这对于并行下载多个文件或获取多条数据很有用。

const requests = [fetch('https://api.example.com/data1'),fetch('https://api.example.com/data2')
];Promise.all(requests).then(responses => Promise.all(responses.map(r => r.json()))).then(data => console.log(data)).catch(error => console.error(error));

上述代码创建了一个包含两个请求的数组,并使用Promise.all来等待所有请求完成。一旦所有的请求都完成,它会将每个响应转换成JSON格式,然后打印出来。

使用 async/await

ES6引入了asyncawait关键字,使得异步代码看起来更像是同步代码,从而提高了可读性和可维护性。

async function getWeather(latitude, longitude) {try {const response = await fetch(`https://api.weatherapi.com/v1/current.json?key=YOUR_API_KEY&q=${latitude},${longitude}`);const data = await response.json();displayWeather(data);} catch (error) {console.error(error);}
}

在这个例子中,我们使用async声明了一个异步函数getWeather,并在函数内部使用await来等待异步操作的结果。这样可以更清晰地组织代码逻辑。

安全性和隐私

当涉及到敏感数据时,确保你的请求是安全的非常重要。这意味着要使用HTTPS而不是HTTP,并且对传输的数据进行加密。此外,对于涉及用户隐私的操作,如位置数据的收集,必须告知用户并获得他们的同意。

用户体验

在设计异步请求时,考虑到用户体验也是很重要的。这意味着要处理好加载状态,例如显示加载指示器,以及在请求失败时给出友好的错误提示。

测试

测试你的异步代码同样重要。你可以使用工具如Jest或Mocha来模拟网络请求,这样就可以在不依赖实际网络的情况下测试你的应用逻辑。

好的,我们已经讨论了许多有关异步请求的基础和进阶话题。现在让我们再深入一些特定的领域,比如错误处理的最佳实践、优化网络请求、以及如何利用现代框架简化异步请求处理。

错误处理的最佳实践

在处理异步请求时,确保你的应用程序能够优雅地处理错误是非常重要的。这不仅包括网络错误,还包括服务器端的错误,比如404 Not Found、500 Internal Server Error等HTTP状态码。

HTTP状态码处理

除了使用catch来捕获网络错误外,还需要检查HTTP响应的状态码。下面是一个改进后的错误处理示例:

async function fetchWeather(latitude, longitude) {try {const response = await fetch(`https://api.weatherapi.com/v1/current.json?key=YOUR_API_KEY&q=${latitude},${longitude}`);if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}const data = await response.json();displayWeather(data);} catch (error) {console.error('Failed to fetch weather:', error);// 显示错误信息给用户displayError(error.message);}
}function displayError(message) {const errorDiv = document.createElement('div');errorDiv.className = 'error-message';errorDiv.textContent = message;document.body.appendChild(errorDiv);
}

在这个例子中,我们不仅捕获了网络错误,还处理了HTTP错误状态码,并且向用户展示了错误信息。

优化网络请求

使用CDN

为了加快数据传输速度,可以利用内容分发网络(Content Delivery Network, CDN),特别是当你的应用程序在全球范围内都有用户时。

请求压缩

确保服务器和客户端都支持请求和响应的压缩,这可以显著减少数据传输量。

缓存策略

合理使用缓存策略可以减少不必要的网络请求。例如,可以使用HTTP缓存头(如Cache-Control)来决定何时重用本地缓存的数据。

利用现代框架简化请求处理

使用Axios

Axios是一个基于Promise的HTTP客户端,它为浏览器和node.js提供了统一的API。它可以简化HTTP请求的处理,并提供了一些开箱即用的功能,如自动转换请求和响应数据为JSON。

import axios from 'axios';async function getWeather(latitude, longitude) {try {const response = await axios.get(`https://api.weatherapi.com/v1/current.json?key=YOUR_API_KEY&q=${latitude},${longitude}`);displayWeather(response.data);} catch (error) {console.error('Failed to fetch weather:', error);displayError(error.message);}
}
使用React Hooks

如果你正在使用React,可以使用useEffect来管理副作用(如API请求),并且使用useState来更新UI。

import React, { useState, useEffect } from 'react';function WeatherComponent() {const [weatherData, setWeatherData] = useState(null);const [errorMessage, setErrorMessage] = useState('');useEffect(() => {navigator.geolocation.getCurrentPosition(position => {fetchWeather(position.coords.latitude, position.coords.longitude);}, error => setErrorMessage('Geolocation is not supported.'));}, []);async function fetchWeather(lat, lon) {try {const response = await fetch(`https://api.weatherapi.com/v1/current.json?key=YOUR_API_KEY&q=${lat},${lon}`);if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}const data = await response.json();setWeatherData(data);} catch (error) {setErrorMessage(error.message);}}return (<div>{weatherData ? (<div><p><strong>Location:</strong> {weatherData.location.name}</p><p><strong>Temperature:</strong> {weatherData.current.temp_c}°C</p><p><strong>Condition:</strong> {weatherData.current.condition.text}</p></div>) : errorMessage ? (<p>{errorMessage}</p>) : (<p>Loading...</p>)}</div>);
}

在这个React组件中,我们使用了useEffect来执行异步请求,并且根据请求的结果更新了状态。这样可以保持UI的响应性和可预测性。

通过上述方法和技术,你可以进一步提升你的Web应用在处理异步请求时的性能、可靠性和用户体验。

相关文章:

JavaScript 第13章:Ajax 与异步请求

在Web开发中&#xff0c;异步请求是一种非常重要的技术&#xff0c;它可以让网页在不重新加载的情况下与服务器交互。本章将介绍两种常用的异步请求技术&#xff1a;XMLHttpRequest 和 Fetch API&#xff0c;以及它们如何用于处理JSON数据交换&#xff0c;并通过一个实战案例—…...

速卖通商品详情接口技术解析及Python代码示例

速卖通商品详情接口技术解析及Python代码示例 速卖通&#xff08;AliExpress&#xff09;作为全球知名的跨境电商平台&#xff0c;其开放平台提供了丰富的API接口&#xff0c;允许开发者集成速卖通的各项功能&#xff0c;实现商品搜索、详情查询、订单管理等一系列操作。本文将…...

邻接表的有向网(C语言代码)

#include <stdio.h> #include <stdlib.h> #define MVNum 100 //最大顶点数 //边表结构体 typedef struct ArcNode { //表结点 int adjvex; //邻接点的位置 struct ArcNode* nextarc; //指向下一个…...

大模型生成PPT大纲优化方案:基于 nVidia NIM 平台的递归结构化生成

大模型生成PPT大纲优化方案&#xff1a;基于 nVidia NIM 平台的递归结构化生成 待解决的问题 生成PPT大纲是一种大模型在办公场景下应用的常见需求。 然而&#xff1a; 目前直接让大模型生成大纲往往是非结构化的&#xff0c;输出格式多样&#xff0c;难以统一和规范&#…...

MRSO算法(JCR2区)

原论文摘要&#xff1a;智能技术的快速发展促使利用自然行为来解决复杂问题的优化算法得以发展。其中&#xff0c;鼠群优化算法&#xff08;Rat Swarm Optimizer&#xff0c;RSO&#xff09;受老鼠的社会和行为特征启发&#xff0c;在各个领域已展现出潜力&#xff0c;但其收敛…...

最新Spring Boot3框架入门教程,基础知识讲解(参考官方文档),同时基于MybatisPlus+MYSQL搭建后台管理系统基础流程(附源码)

本文所涉及的代码以及相关文件均上传至仓库:GitHub - yang66-hash/XDPropertyManagementSystemDemo: This is a demo template based on SpringBoot3 in the background of property management system. Spring Boot 是由 Pivotal 团队开发的一款开源框架&#xff0c;它可以帮助…...

导数的概念及在模型算法中的应用

一. 导数概念与计算 1. 导数的物理意义&#xff1a; 瞬时速率。一般的&#xff0c;函数yf(x)在x处的瞬时变化率是 2. 导数的几何意义&#xff1a; 曲线的切线&#xff0c;当点趋近于P时&#xff0c;直线 PT 与曲线相切。容易知道&#xff0c;割线的斜率是当点趋近于 P 时&…...

获取首日涨停封盘后第二次交易日上涨/下跌的概率

有许多投资者喜欢在股票涨停封盘后&#xff0c;跟进买入。普通股民会认为一个能在今日涨停封盘的股票&#xff0c;证明其上市公司正有十分重大的利好信息&#xff0c;只需要跟进购买便可以获取短期利益。 我们用数据来看一下在当日涨停封盘后&#xff0c;第二次交易日是上涨还…...

shell $ 用法

Shell脚本中$符号的几种用法小结_linux shell_脚本之家 Shell 传递参数 | 菜鸟教程 $ 符号说明$0Shell 的命令本身1到9表示 Shell 的第几个参数$?显示最后命令的执行情况$#传递到脚本的参数个数$$脚本运行的当前进程 ID 号$*以一个单字符串显示所有向脚本传递的参数$!后台运行…...

如何用支付宝实现靠脸吃饭

还记得上学时&#xff0c;每当下课铃声响起&#xff0c;我们就会像一群脱缰的野马一样&#xff0c;浩浩荡荡地冲向食堂。最令人崩溃的时刻莫过于终于到达打饭窗口前排时&#xff0c;却发现饭卡忘带了&#xff01;但现在&#xff0c;这种情况将不再发生。许多学校食堂已经配备了…...

Visual Studio的实用调试技巧总结

对于很多学习编程的老铁们来说&#xff0c;是不是也像下面这张图一样写代码呢&#xff1f; 那当我们这样编写代码的时候遇到了问题&#xff1f;大家又是怎么排查问题的呢&#xff1f;是不是也像下面这张图一样&#xff0c;毫无目的的一遍遍尝试呢&#xff1f; 这篇文章我就以 V…...

graphrag学习总结

学习视频&#xff1a;b站链接 项目链接 GraphRAG 的基本概念 Document&#xff08;文档&#xff09;&#xff1a;系统中的输入文档。这些文档要么代表CSV中的单独行&#xff0c;要么代表单独的txt文件。 TextUnit&#xff08;文本块&#xff09;&#xff1a;要分析的文本块。…...

专题:贪心算法(已完结)

1.分发饼干 方法一&#xff1a;用最大的胃口 找到最大的饼干&#xff08;先遍历胃口&#xff09; class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {// 主要思路 用最大的饼干找最大的胃口sort(g.begin(),g.end());so…...

Hadoop的三种运行模式:单机模式、伪分布式模式和完全分布式模式

单机模式 单机模式是Hadoop最简单的运行模式。在单机模式下&#xff0c;所有Hadoop组件都运行在单个机器上&#xff0c;包括HDFS、MapReduce等。由于只有一个节点参与计算&#xff0c;单机模式适用于开发和测试阶段&#xff0c;不适合用于处理大规模数据。在单机模式下&#xf…...

JavaScript将array数据下载到Excel中

具体代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widt…...

【前端】Bootstrap:快速开始

Bootstrap 是一个功能强大且易于使用的前端框架&#xff0c;专门用于创建响应式和移动优先的网页。学习Bootstrap不仅可以帮助你快速构建现代网页&#xff0c;还可以提升你对前端开发流程的理解。本教程将从基础概念开始&#xff0c;逐步引导你掌握Bootstrap&#xff0c;并通过…...

文献阅读(222) VVQ协议死锁

题目&#xff1a;VVQ: Virtualizing Virtual Channel for Cost-Efficient Protocol Deadlock Avoidance时间&#xff1a;2023会议&#xff1a;HPCA研究机构&#xff1a;KAIST request-reply协议死锁如下图所示&#xff0c;每个node收到request之后发送reply&#xff0c;但是想…...

Node.js管理工具NVM

nvm&#xff08;Node Version Manager&#xff09;是一个用于管理多个 Node.js 版本的工具。以下是 nvm 的使用方法和一些常见命令&#xff1a; 一、安装 nvm 下载 nvm&#xff1a; 地址&#xff1a;https://github.com/coreybutler/nvm-windows/releases访问 nvm 的 GitHub 仓…...

云原生后端

云原生后端&#xff08;Cloud-Native Backend&#xff09;是指在云计算环境中&#xff0c;利用云原生技术&#xff08;如容器、微服务、服务网格等&#xff09;构建和部署后端应用程序的一种方法。以下是对云原生后端的详细讲解&#xff1a; 1. 定义 云原生是一种设计和构建应…...

充电宝哪个品牌值得买?2024年五款靠谱充电宝推荐

哪个品牌充电宝值得买&#xff1f;用过这么多款充电宝&#xff0c;个人还是觉得充电快、小巧便携的充电宝使用会更加的方便&#xff01;在当今快节奏的生活中&#xff0c;手机已成为我们不可或缺的伙伴。然而&#xff0c;随着智能手机功能的日益强大&#xff0c;电池续航问题也…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...