每个 HTTP 请求的 5 个支柱

2025-06-04

每个 HTTP 请求的 5 个支柱

要求

请求,或者说 HTTP 请求,是向服务器发送操作,用于获取某些内容或发送某些信息。请求包含服务器的 URL、请求头和请求主体。

大部分解释的内容对于请求某些信息很重要,但也可以在发送信息时应用。

加载中

向用户显示加载信息是请求的重要步骤,因为我们永远不知道网络上会发生什么,也许连接很慢,也许服务器因为大量请求而变慢。

显示加载器或表明请求仍在进行的文本是一个额外的步骤,可以让您的应用程序看起来更专业,并且比认为每个人都有快速的互联网连接更加用户友好。

您可以在自己喜欢的浏览器(例如 Firefox 或 Google Chrome)中从开发者控制台模拟减慢的请求。

错误

网络中会发生各种事情,除了代码内部发生的事情之外,我们无法控制一切。

网络可能会暂时关闭,或者用户开启了飞行模式,又或者服务器已经宕机一段时间了。我们永远不知道会出现什么样的问题,也不知道什么时候会发生,但我们知道可能会出现问题,而且我们必须考虑到这一点。

在代码中考虑这些事情是一种很好的做法,特别是在 JavaScript 中,因为发送请求通常涉及使用 Promise,而承诺可能处于被拒绝的状态。

您还可以从开发者控制台在浏览器中模拟离线连接。

可取消

如果您计划通过远程 API 向用户提供数据,至少要提供一种取消这些请求的方法。

这是一个很好的做法,并且可以在任何应用程序中增加用户体验,因为从远程服务器获取巨大的有效负载对于使用数据计划的用户来说可能是昂贵的,并且拥有选择权可以很好地向用户表明您正在考虑每个人,即使是那些无法承担大量数据传输的用户。

使用 JavaScript 和 Web API Fetch,您可以将信号与 Abort Controller 一起使用,以提供取消请求的方法。

验证

终于,你发送了请求,一切按计划进行,并收到了成功的回复。是这样吗?

如何确保服务器的响应在一天、一周甚至一年后不会改变?你的应用程序或许能运行一段时间,但如果有人决定发送一个带有属性的对象而不是像往常一样发送数组,你可能会遇到麻烦,因为你会尝试迭代对象而不是数组,而这在 JavaScript 中是无法实现的。

数据验证是一个重要的步骤,在某些情况下也可能是强制性的,因为即使您知道今天在做什么,并且您是前端和后端应用程序的唯一开发人员,一年后您可能并不孤单,人们可能会加入战斗并帮助您。

如果您从长假回来并且 API 已经发生变化,至少通过数据验证您知道这是一个您可以解决的情况并且您的应用程序不会突然崩溃(并且您甚至可能会得到更好的错误,这将使您能够比没有数据验证更快地解决这个错误)。

此外,通过数据验证,您可以依赖像 TypeScript 这样的强类型语言来确保一旦解析和验证了这些数据,您就可以 100% 确定可以对其进行迭代,而不必担心它可能在不久的将来发生变化。

例子

以下是 React 中初学者应用程序的示例。

import React, { useEffect, useState } from "react";

export const App = () => {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users").then(response => {
      return response.json();
    }).then(newUsers => {
      setUsers(newUsers);
    });
  }, []);

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.username}</li>
      ))}
    </ul>
  );
};
Enter fullscreen mode Exit fullscreen mode

如您所见,没有加载状态,没有可取消的请求,没有错误说明,也没有数据验证。

添加完所有这些东西后,它可能看起来是这样的。

import React, { Fragment, useRef, useEffect, useState, useCallback } from "react";

const isValidUser = input => {
  return typeof input === "object"
    && input !== null
    && typeof input.id === "number"
    && typeof input.username === "string";
}

const isValidUsers = users => {
  if (!Array.isArray(users)) {
    return false;
  }

  if (!users.every(user => isValidUser(user))) {
    return false;
  }

  return true;
}

export const App = () => {
  const [users, setUsers] = useState([]);
  const abortController = useRef(null);
  const [error, setError] = useState(null);
  const [loading, setLoading] = useState(false);

  const cancel = useCallback(() => {
    abortController?.current?.abort();
  }, [abortController]);

  useEffect(() => {
    abortController.current = new AbortController();
    const { signal } = abortController.current;

    setError(null);
    setLoading(true);

    fetch("https://jsonplaceholder.typicode.com/users", {
      signal
    }).then(response => {
      if (response.ok) {
        return response.json();
      }

      return Promise.reject(new Error("Something went wrong"));
    }).then(newUsers => {
      if (!isValidUsers(newUsers)) {
        throw new Error("Wrong response from the server");
      }

      setUsers(newUsers);
    }).catch(error => {
      setError(error);
    }).finally(() => {
      setLoading(false);
    });
  }, []);

  return (
    <Fragment>
      {loading && (
        <small>Loading, please wait...</small>
      )}
      {error && (
        <small>{error.message}</small>
      )}
      <button onClick={cancel}>Cancel</button>
      <ul>
        {users.map(user => (
          <li key={user.id}>{user.username}</li>
        ))}
      </ul>
    </Fragment>
  );
};
Enter fullscreen mode Exit fullscreen mode

当然,由于没有采用任何样式,所以看起来很糟糕,但至少你明白了。

我们添加了取消请求的方式、让用户放心的加载指示、任何错误的显示以及基本的数据验证机制,以确保我们获得的数据没有损坏或被更改。

结论

我们看到,为了构建可靠的应用程序,每当我们向服务器发出请求时,都必须遵循 5 个步骤:

  • 发送适当的请求
  • 显示加载状态
  • 如果有错误则显示
  • 使请求可取消
  • 验证我们收到的数据

如果您设法遵循这些步骤,您将构建经过时间考验且坚固的高度可靠应用程序。

这会立即让您的应用程序在用户眼中变得更好。

这些概念与 JavaScript 或 React 无关,只要您遵循这些步骤,它们就可以应用于几乎任何语言或任何框架和库。

文章来源:https://dev.to/aminnairi/the-5-pillars-of-every-http-request-18ld
PREV
25 款 Chrome/Firefox 扩展程序,让您的生活更轻松 [2020]
NEXT
为食谱设计关系数据库