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

所以,在今天的帖子中,我们将讨论用Javascript发送HTTP请求的不同方法。从语言提供的本地选项开始,我们将查看以下五个模块,并使用它们发送不同类型的HTTP请求。

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

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

下面是如何发送GET请求和使用XMLHttpRequest API从远程API异步检索数据:

代码语言:javascript复制//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请求的过程包括三个步骤:

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

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

代码语言:javascript复制// 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访问的上传事件。上传字段。当请求体必须携带大量数据(如图像、文件等)时,这些事件处理程序帮助我们跟踪数据上传进度。

XMLHttpRequest的优点由于该方法是本地支持的,所以它与所有现代浏览器版本兼容。消除对外部依赖项的需要。允许在基本级别访问和操作异步HTTP请求。XMLHttpRequest的缺点代码是冗长的和不必要的长。不支持async/await或基于承诺的语法。大多数较新的HTTP请求包在复杂的XMLHttpRequest API上提供简单的抽象。FetchFetch是一个简化的、现代的本机Javascript API,用于发出HTTP请求。它内置了对承诺的支持,并改进了前面讨论的XMLHttpRequest冗长的语法。作为一种考虑到现代应用程序和开发人员需求而构建的API, Fetch已经成为当今最流行的用Javascript发送HTTP请求的方式之一。

按照基于promise的语法,我们可以使用Fetch从客户端发送HTTP请求,如下例所示。

代码语言:javascript复制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))

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

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

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

让我们使用async/await来尝试这个实现:

代码语言:javascript复制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请求。易于学习和使用任何水平的问题。支持基于承诺的实现,允许我们写干净,简洁的代码。在XMLHttpRequest上提供额外的特性,例如将请求和响应对象与本机缓存API集成,并发送无cors请求。Fetch的缺点缺少XMLHttpRequest支持的一些有用特性,比如终止请求和监视请求进展。(但是,它允许使用单独的AbortController对象来控制请求中止和超时。)即使发生HTTP错误,也接受响应。我们必须手动检查HTTP错误并处理它们。与Internet Explorer不兼容,不过希望这不再重要了。AxiosAxios是用Javascript发出HTTP请求的最流行的第三方包之一。它在底层与原生XMLHttpRequest API一起工作,为解决诸如拦截HTTP请求和同时发送请求等独特问题带来了一组方便和通用的特性。与Fetch类似,它支持处理异步请求的承诺。

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

代码语言:javascript复制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数据,我们可以通过响应访问这些数据。数据字段。Axios还在其catch方法中捕获HTTP错误,从而无需在处理响应之前专门检查状态代码。在catch方法内部,我们可以使用一个错误来区分HTTP错误。响应检查,它存储HTTP错误代码。

为了使用Axios发送POST请求,我们使用专用的Axios . POST()方法,如下例所示,使用async/await实现:

代码语言:javascript复制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还为许多独特的用例提供了解决方案,我们在这里不讨论这些用例。

Axios优点提供简单、简洁和易于学习的语法。支持在许多其他可用HTTP包中不可用的多功能特性集。其中包括拦截HTTP请求、同时发送请求、终止已发送请求、自动JSON数据转换、监控请求进度等。兼容所有主要浏览器版本,包括Internet Explorer。为XSRF保护提供客户端支持。Axios 缺点向应用程序添加一个外部依赖项,因为该模块不是本机的。SuperAgentSuperAgent是最早引入Javascript用于发送HTTP请求的第三方包之一。与Axios类似,它在其实现中使用了XMLHttpRequest API,并提供了一组对许多请求处理任务有用的全面特性。该包既支持基于承诺的实现,也支持基于回调的实现。

当使用SuperAgent发送HTTP请求时,我们可以依赖它的专用方法来发起特定类型的请求。例如,我们可以使用superagent.get()方法发送GET请求,如下例所示。

代码语言:javascript复制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)

}

})

使用基于promise的语法,SuperAgent遵循与Axios类似的发送GET请求的模式。它自动地将响应体解析为Javascript对象,而不需要开发人员的干涉。它还在catch方法中捕获HTTP错误,我们可以使用错误来识别该方法。响应领域。如果请求由于网络相关的错误而失败,则这些错误。响应和错误。状态字段将保持未定义。

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

代码语言:javascript复制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调用、缓存请求和响应数据、排队和调整请求等。兼容所有主流浏览器版本。然而,你必须使用polyfill为较早版本的IE浏览器启用功能。SuperAgent缺点添加一个外部依赖项,因为该模块不是本机的。不支持监听请求进度。KyKy是一个相对较新的Javascript包,可用于从web应用程序的前端发出异步HTTP请求。它构建在Fetch API之上,具有更简单的语法和额外的功能。

Ky为使用其专用的HTTP方法发出请求提供了简单的语法。下面是一个使用Ky和async/await发送GET请求的示例。

代码语言:javascript复制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请求:

代码语言:javascript复制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优点提供一个简单、轻量级、基于承诺的HTTP请求API。通过支持请求超时、重试和监控进度等特性,解决了本机Fetch API中的一些限制。提供在生命周期内修改请求的钩子:beforeRequest, afterResponse, beforeRetry等。支持所有现代浏览器,如Chrome, Firefox, Safari。对于ie浏览器的支持,Ky提供了一个替代包,Ky-universal,不知道他们为什么还要麻烦。Ky缺点相对于本文中讨论的其他成熟的多功能选项来说,这是一个相对较新的包。需要添加外部依赖项。总结近年来,许多本机和第三方模块被引入到Javascript中,用于发送HTTP请求。在我们今天讨论的五种方法中,我们涉及了传统的、流行的,甚至是相对较新的完成这项任务的方法,从而为开发人员提供了不同选项的完整概述。

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