现代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请求的正确方法。