在JavaScript中执行HTTP请求的5种方法

2021年11月28日05:20:26 发表评论 1,889 次浏览

现代 Javascript 提供了多种向远程服务器发送 HTTP 请求的方法。从原生 XMLHttpRequest 对象到像 Axios 这样的第三方库,拥有如此多样化的选择集合使得在 Web 应用程序中请求和动态加载内容比以往任何时候都更加轻松。

JavaScript如何执行HTTP请求?在今天的文章中,我们将讨论在 Javascript 中发送 HTTP 请求的不同方式。从语言提供的本机选项开始,我们将查看以下五个模块并使用它们发送不同类型的 HTTP 请求。

  • XMLHttpRequest
  • Fetch
  • Axios
  • SuperAgent
  • Ky

让我们开始吧!


XMLHttpRequest

JavaScript执行HTTP请求的方法:XMLHttpRequest 是 Javascript 中的原生 API,它封装了发送 HTTP 请求的逻辑,而无需刷新加载的网页(AJAX 请求)。尽管开发人员现在很少直接使用 XMLHttpRequest,但它仍然是许多流行的 HTTP 请求模块下工作的构建块。

因此,了解如何使用 XMLHttpRequest 方法发送请求可以帮助你处理第三方库不支持的独特用例。

JavaScript执行HTTP请求示例:以下是我们如何使用 XMLHttpRequest API 从远程 API 发送 GET 请求和异步检索数据的方法:

//create XMLHttpRequest object
const xhr = new XMLHttpRequest()
//open a get request with the remote server URL
xhr.open("GET", "https://world.openfoodfacts.org/category/pastas/1.json")
//send the Http request
xhr.send()

//EVENT HANDLERS

//triggered when the response is completed
xhr.onload = function() {
  if (xhr.status === 200) {
    //parse JSON datax`x
    data = JSON.parse(xhr.responseText)
    console.log(data.count)
    console.log(data.products)
  } else if (xhr.status === 404) {
    console.log("No records found")
  }
}

//triggered when a network-level error occurs with the request
xhr.onerror = function() {
  console.log("Network error occurred")
}

//triggered periodically as the client receives data
//used to monitor the progress of the request
xhr.onprogress = function(e) {
  if (e.lengthComputable) {
    console.log(`${e.loaded} B of ${e.total} B loaded!`)
  } else {
    console.log(`${e.loaded} B loaded!`)
  }
}

如本例所示,使用 XMLHttpRequest 发送 GET 请求的过程包括三个步骤:

  • 创建 XMLHttpRequest
  • 打开缩进类型的HTTP请求
  • 发送请求

一旦请求被发送,我们就可以使用 XMLHttpObject 提供的事件处理程序来处理它的响应。在这里,我们使用了两个事件处理程序:onloadonerror,和onprogress。这里需要注意的是,onerror 方法只处理与请求相关的网络级错误。为了识别 HTTP 错误,我们必须专门检查 onload 方法中的 HTTP 状态代码。

我们可以按照类似的模式使用 XMLHttpRequest 发送 POST 请求。

// create XMLHttpRequest object
const xhr = new XMLHttpRequest()
// open a POST request
xhr.open("POST", "/food")
// set content-type header to JSON
xhr.setRequestHeader("Content-Type", "application/json");
// send JSON data to the remote server
xhr.send(JSON.stringify(food))

// Event Handlers

// track data upload progress
xhr.upload.onprogress = function(e) {
  console.log(`${e.loaded}B of ${e.total}B uploaded!`)
}

// triggered when data upload is finished
xhr.upload.onload = function(e) {
  console.log("Upload completed")
}

// triggered when the response is fully received
xhr.onload = function() {
  console.log(xhr.status)
}

// triggered due to a network-level error
xhr.onerror = function() {
  console.log("Network error occurred")
}

早期 GET 和当前 POST 请求之间的主要区别之一是在发布 JSON 数据时显式设置内容类型标头。此外,与 GET 请求相比,POST 请求可以触发额外的事件类型。它们是通过 xhr.upload 字段访问的上传事件。当请求主体必须携带大量数据(例如图像、文件等)时,这些事件处理程序可帮助我们跟踪数据上传进度。

XMLHttpRequest 的优点

  • 由于该方法是本机支持的,因此它与所有现代浏览器版本兼容。
  • 消除了对外部依赖的需要。
  • 允许在基本级别访问和操作异步 HTTP 请求。

XMLHttpRequest 的缺点

  • 代码冗长且不必要地长。
  • 不支持 async/await 或基于 Promise 的语法。
  • 大多数较新的 HTTP 请求包提供对复杂 XMLHttpRequest API 的简单抽象。

Fetch

JavaScript执行HTTP请求的方法:Fetch 是一种简化的现代原生 Javascript API,用于发出 HTTP 请求。它内置了对 promise 的支持,并改进了之前讨论的 XMLHttpRequest 的冗长语法。作为考虑到现代应用程序和开发人员需求而构建的 API,Fetch 已成为当今在 Javascript 中发送 HTTP 请求的最流行方式之一。

JavaScript如何执行HTTP请求?遵循基于 Promise 的语法,我们可以使用 Fetch 从客户端发送 HTTP 请求,如本示例所示。

fetch("https://world.openfoodfacts.org/category/pastas/1.json")
  .then(response => {
    // indicates whether the response is successful (status code 200-299) or not
    if (!response.ok) {
      throw new Error(`Request failed with status ${reponse.status}`)
    }
    return response.json()
  })
  .then(data => {
    console.log(data.count)
    console.log(data.products)
  })
  .catch(error => console.log(error))

通过使用更简单的语法和承诺,Fetch 显着降低了代码的复杂性和冗长性。在这个实现中,我们必须使用response.ok字段来检查响应是否包含 HTTP 错误,因为 catch 方法中捕获的错误属于网络级别,而不是应用程序级别。

fetch 方法接受一个配置对象作为第二个参数,以允许轻松操作 HTTP 字段,如标头、内容类型、请求方法等。你可以在其官方文档中找到 Fetch 支持的配置选项的完整列表 。

使用 Fetch 发出 POST 请求也遵循与前一个示例类似的模式。在这里,我们使用config对象来指定请求方法,并传递需要发布的数据。

JavaScript执行HTTP请求示例:让我们使用 async/await 来试试这个实现:

async function postData () {
  const food = {
    name: "Bread",
    weight: 450,
    quantity: 3
  }

  const response = await fetch("/food", {
    method: "POST",
    body: JSON.stringify(food),
    headers: {
      "Content-Type": "application/json"
    }
  })

  if (!response.ok) {
    throw new Error(`Request failed with status ${reponse.status}`)
  }
  console.log("Request successful!")
}

Fetch 的优点

  • 提供一种简化的原生方式来在 Javascript 中发出 HTTP 请求。
  • 易于学习和用于任何级别的问题。
  • 支持基于 Promise 的实现,让我们可以编写更简洁、简洁的代码。
  • 在 XMLHttpRequest 上提供附加功能,例如将 Request 和 Response 对象与本机 Cache API 集成并发送 no-cors 请求 。

获取的缺点

  • 缺少 XMLHttpRequest 支持的一些有用功能,例如中止请求和监控请求进度。(但是,它允许使用单独的AbortController 对象来控制请求中止和超时。)
  • 即使发生 HTTP 错误,也接受响应。我们必须手动检查 HTTP 错误并处理它们。
  • Internet Explorer不兼容 ,但希望这不再重要。

Axios

Axios 是最流行的第三方包之一,用于在 Javascript 中发出 HTTP 请求。它在底层与原生 XMLHttpRequest API 配合使用,带来了一组方便且通用的功能,用于解决诸如拦截 HTTP 请求和发送同步请求等独特问题。与 Fetch 类似,它支持用于处理异步请求的承诺。

使用 Axios 发出 GET 请求时,我们可以使用专用axios.get()方法来编译请求。在这里,我们展示了一个实现示例:

axios.get("https://world.openfoodfacts.org/category/pastas/1.json")
  .then(response => {
    // access parsed JSON response data using response.data field
    data = response.data
    console.log(data.count)
    console.log(data.products)
  })
  .catch(error => {
    if (error.response) {
      //get HTTP error code
      console.log(error.reponse.status)
    } else {
      console.log(error.message)
    }
  })

正如这个例子所示,与 Fetch 相比,Axios 减少了我们在发送 HTTP 请求时必须做的工作量。它会自动解析接收到的 JSON 数据,我们可以通过 response.data 字段访问这些数据。Axios 还在其 catch 方法中捕获 HTTP 错误,从而无需在处理响应之前专门检查状态代码。在 catch 方法中,我们可以使用 error.response 检查来区分 HTTP 错误,该检查存储 HTTP 错误代码。

对于使用 Axios 发送 POST 请求,我们使用专用axios.post()方法作为以下示例,使用 async/await 实现,显示:

async function postData () {
  const food = {
    name: "Bread",
    weight: 450,
    quantity: 3
  }

  try {
    const response = await axios.post("/food", food)
    console.log("Request successful!")
  } catch (error) {
    if (error.response) {
      console.log(error.reponse.status)
    } else {
      console.log(error.message)
    }
  }
}

同样,Axios 通过在没有我们拦截的情况下自动将 Javascript 对象转换为 JSON 来简化此实现。这些 Axios 方法还接受指定 HTTP 配置的最终参数。

除了这些基本功能之外,Axios 还为许多我们不会在这里讨论的独特用例提供了解决方案。但是,如果你想更深入地了解在 Javascript 和 Node.js 中使用 Axios,你可以 在我们的博客上阅读这篇Axios 深入指南。

Axios 的优点

  • 提供简单、简洁且易于学习的语法。
  • 支持许多其他可用 HTTP 包中不可用的多种功能。其中包括拦截 HTTP 请求、发送并发请求、中止发送的请求、自动 JSON 数据转换、监控请求进度等。
  • 与所有主要浏览器版本兼容,包括 Internet Explorer。
  • 为 XSRF 保护提供客户端支持。

Axios 的缺点

  • 由于模块不是本机的,因此向应用程序添加外部依赖项。

SuperAgent

JavaScript执行HTTP请求的方法:SuperAgent 是最早引入 Javascript 的第三方包之一,用于发出 HTTP 请求。与 Axios 类似,它在其实现中使用了 XMLHttpRequest API,并附带了一组在许多请求处理任务中有用的综合功能。该包支持基于承诺和基于回调的实现。

JavaScript执行HTTP请求示例:使用 SuperAgent 发送 HTTP 请求时,我们可以依靠其专用方法来发起特定类型的请求。例如,我们可以使用 superagent.get() 方法发送 GET 请求,如本示例所示。

superagent
  .get("https://world.openfoodfacts.org/category/pastas/1.json")
  .then(response => {
    // get parsed JSON response data
    data = response.body
    console.log(data.count)
    console.log(data.products)
  })
  .catch(error => {
    if (error.response) {
      console.log(error.status)
    } else {
      console.log(error.message)
    }
  })

使用基于承诺的语法,SuperAgent 遵循与 Axios 类似的模式来发送 GET 请求。它会自动将响应正文解析为 Javascript 对象,而无需开发人员干预。它还在 catch 方法中捕获 HTTP 错误,我们可以使用 error.response 字段来识别。如果请求由于与网络相关的错误而失败,这些 error.response 和 error.status 字段将保持未定义。

我们可以以类似的方式使用 SuperAgent 发送 POST 请求。

superagent
  .post("/food")
  .send(food)
  .then(response => console.log("Request successful!"))
  .catch(error => {
    if (error.response) {
      console.log(error.status)
    } else {
      console.log(error.message)
    }
  })

默认情况下,SuperAgent 假定传递的数据是 JSON 格式,并自行处理数据转换和设置内容类型标头。为了传递随 POST 请求发送的数据,我们使用 SuperAgent 的send()方法。

SuperAgent 的优点

  • 为发送 HTTP 请求提供易于使用、基于承诺的解决方案。
  • 它是 Javascript 中一个成熟且得到良好支持的模块。
  • 如果在发出请求时发生与网络相关的或其他暂时性错误,则支持重试请求。
  • 支持在不断发展的插件集的帮助下扩展包的功能 。这些插件添加到 SuperAgent 的一些功能示例包括模拟模拟 HTTP 调用、缓存请求和响应数据、排队和限制请求等。
  • 与所有主要浏览器版本兼容。但是,你必须为早期版本的 Internet Explorer 使用 polyfill 来启用诸如 promise 支持之类的功能,同样,IE?谁在乎这一点,对吧?

SuperAgent 的缺点

  • 添加外部依赖项,因为该模块不是本机的。
  • 不支持监控请求进度。

Ky

JavaScript如何执行HTTP请求?Ky 是一个相对较新的 Javascript 包,可用于从 Web 应用程序的前端发出异步 HTTP 请求。它建立在本机 Fetch API 之上,具有更简单的语法和附加功能。

JavaScript执行HTTP请求示例:Ky 提供了一种简单的语法来使用其专用的 HTTP 方法发出请求。这是使用 Ky 和 async/await 发送 GET 请求的示例。

async function getData () {
  try {
    const data = await ky.get("https://world.openfoodfacts.org/category/pastas/1.json").json()
    console.log(data.count)
    console.log(data.products)
  } catch (error) {
    if (error.response) {
      console.log(error.response.status)
    } else {
      console.log(error.message)
    }
  }
}

我们可以按照类似的模式发送 POST 请求:

async function postData () {
  try {
    const response = await ky.post("/food", { json: food })
    console.log("Request successful!")
  } catch (error) {
    if (error.response) {
      console.log(error.reponse.status)
    } else {
      console.log(error.message)
    }
  }
}

Ky的优点

  • 提供一个简单的、轻量级的、基于 Promise 的 API 来发出 HTTP 请求。
  • 解决了本机 Fetch API 中的一些限制,支持请求超时、重试和监控进度等功能。
  • 提供用于在请求的生命周期中修改请求的钩子:beforeRequest、afterResponse、beforeRetry 等。
  • 支持所有现代浏览器,如 Chrome、Firefox、Safari。对于 Internet Explorer 支持,Ky 提供了一个替代软件包Ky-Universal ,不知道为什么他们仍然打扰。

Ky 的缺点

  • 与本文中讨论的其他成熟、通用的选项相比,这是一个相对较新的软件包。添加外部依赖项。

JavaScript执行HTTP请求的方法总结

近年来,一些原生和第三方模块被引入到 Javascript 中,用于发送 HTTP 请求。在我们今天讨论的五种方法中,我们触及了完成此任务的传统、流行甚至相对较新的方法,以完整概述你作为开发人员可用的不同选项。

虽然这些方法各有优缺点,但你可以在仔细考虑你的需求后选择最适合在你的 Web 应用程序中使用的方法。我们希望这篇文章能帮助你进行分析并确定在你未来的项目中发送 HTTP 请求的正确方法。

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: