JavaScript Fetch API 入门
过去,有两种方式发出请求。一种是使用XMLHttpRequest。另一种是使用 jQuery,即ajax()方法。幸运的是,JavaScript 现在提供了第三种方式——Fetch API。在本教程中,您将学习 JavaScript Fetch API 入门所需的所有知识。
简要介绍
Fetch API 是 JavaScript 标准中新增的 API。它提供了一种更简单、更清晰的服务器请求方式。更棒的是,它基于PromiseXMLHttpRequest实现。这使得它使用起来更简单、更友好。这也是它比 JavaScript和 jQuery 更受欢迎的原因ajax()。
JavaScript Fetch API 基础知识
当你想使用 fetch API 发出请求时,你通常需要两样东西。第一个是fetch()方法。这个方法负责发出请求。它需要一个参数,即你想要发出请求的路径或 URL。除了这个参数之外,你还可以通过配置对象来提供这个方法。
此配置对象是可选的。它允许您为请求设置各种设置。例如,您可以添加标头、包含一些数据的正文、设置跨域请求模式、启用缓存、允许或禁止重定向、指定引荐来源网址和 referrerPolicy 等等。您可以在MDN上找到所有可用选项。
// Fetch syntax
fetch(someURL, {})
// or with optional config object
fetch(someURL, {/* settings go here */})
使用承诺处理函数处理获取
您需要的第二件事是Promise 处理函数。正如我们简要讨论过的,fetch API 基于 Promise。这意味着每次您发出请求时,结果(fetch()方法返回的数据)都将是一个 Promise。为了处理这个 Promise,您需要使用其中一个 Promise 处理函数。
您可能最常使用的两个处理函数是then()和catch()。then()处理函数帮助您处理 Promise 的已实现状态。这适用于已解决和已拒绝的 Promise。处理已拒绝 Promise 的另一种方法是使用catch()。
和 都then()可以catch()处理已拒绝的 Promise。但是,只有then()可以处理已解决的 Promise。因此,请确保then()至少使用 来处理 Promise 的已解决状态。对于已拒绝状态,请确定是否要使用then()和catch()。
当 fetch promise 被 fulfilled 时,它收到的数据会自动传递给附加的处理函数。当你需要处理这些数据时,你必须在这些处理函数内部进行操作。如果你想让这些数据在处理函数外部可用,可以将数据赋值给某个外部变量。
// Use fetch() method with promise handler functions
fetch(someUrl)
.then(response => {
// When promise gets resolved
// log received data to console
console.log(response)
})
.catch(error => {
// If promise gets rejected
// log the error to console
console.log(error)
})
// Real-world example
fetch('https://sv443.net/jokeapi/v2/joke/Programming')
// Convert response to JSON format
.then(response => response.json())
// Log the response JSON
.then(jsonData => console.log(jsonData))
.catch(error => {
// If promise gets rejected
// log the error to console
console.log(error)
})
// Output:
// {
// error: false,
// category: 'Programming',
// type: 'twopart',
// setup: 'Programming is like sex.',
// delivery: 'Make one mistake and you end up supporting it for the rest of your life.',
// flags: {
// nsfw: true,
// religious: false,
// political: false,
// racist: false,
// sexist: false
// },
// id: 8,
// lang: 'en'
// }
如上例所示,你可以将 Promise 处理函数一个接一个地串联起来。建议将函数放在then()最前面,将 放在catch()后面。如果你还使用了finally(),建议将其放在最后。
使用 await 处理 fetch
如果您不想使用 Promise 处理函数,另一个选择是await。它await做两件事。首先,它会暂停周围代码的执行,直到跟在这个关键字后面的 Promise 被满足为止。其次await,它替换了then()函数。它会自动提取 Promise 返回的数据并将其赋值给一个变量。
如果要使用 ,需要记住两点await。首先,请在try...catch语句中使用它。await 是对then()函数的补充,但它并不对 进行补充catch()。如果要捕获可能出现的任何错误,可以使用 catchtry...catch语句。
第二件事是,在顶级 awaitawait发布之前,你只能在异步函数中使用。这就是你能做的。fetch()与 with 一起使用await。然后,用 with 语句包装这两个try...catch,并将其全部放入async函数中。
// Create async function
async function makeRequest() {
// Use try...catch statement
try {
// Use await and make fetch request
const responseData = await fetch('https://sv443.net/jokeapi/v2/joke/Any')
// Convert the response to JSON format
const responseJSON = await responseData.json()
// Log the converted JSON
console.log(responseJSON)
}
catch (error) {
// Log any error
console.log(error)
}
}
// Call the makeRequest()
makeRequest()
// Output:
// {
// error: false,
// category: 'Miscellaneous',
// type: 'twopart',
// setup: "Mom asked me where I'm taking her to go out to eat for mother's day.",
// delivery: 'I told her, "We already have food in the house".',
// flags: {
// nsfw: false,
// religious: false,
// political: false,
// racist: false,
// sexist: false
// },
// id: 89,
// lang: 'en'
// }
处理响应
当你发出请求时,promise 会返回fetch()一个响应对象。该对象包含从服务器接收的信息以及各种方法。我们可以使用这些方法来处理数据。这些方法是clone()、redirect()、arrayBuffer()、formData()、和。blob()text()json()
该clone()方法创建响应的克隆。该redirect()方法创建一个新的响应,但使用不同的 URL。该方法arrayBuffer()将响应以ArrayBuffer 的形式返回。该方法将formData()响应以FormData对象的形式返回。该blob()方法将响应以 Blob 的形式返回。
以字符串或文本形式返回text()响应。最后一个方法,即json(),以 JSON 格式返回响应。您应该使用哪种方法来解析响应取决于您期望的数据类型。例如,如果您期望接收 JSON 格式的数据,则使用json(),如果是文本格式,则使用text(),等等。
这些方法的优点在于,您无需知道预期的响应是什么。即使您选择了错误的方法,这些解析响应的方法(例如text()和 )json()通常也能正常工作。例如,假设您使用了text()方法,但响应却是 JSON 格式。
在这种情况下,该text()方法将能够选择该 JSON 并将其解析为字符串。结果基本上是字符串化的 JSON。但是,该方法不适用于文本响应和json()。json()需要特定的语法。如果响应是纯文本,并且您使用json(),则会收到语法错误。
因此,如果您不确定应该期望哪种类型的响应,请使用text()。在最坏的情况下,您会得到一些字符串化的 JSON,这样您就知道应该使用json()哪种格式。如果您期望其他格式,请使用相应的方法:response.formData(),response.blob()或response.arrayBuffer()。
// Example no.1:
// Parsing response as a text
async function makeRequest() {
// Use try...catch statement
try {
// Make fetch request
const responseData = await fetch('https://sv443.net/jokeapi/v2/joke/Programming')
// Parsing as Text happens here:
// Parse the response as a text
const responseText = await responseData.text()
// Log the text
console.log(responseText)
}
catch (error) {
// Log any error
console.log(error)
}
}
// Call the makeRequest()
makeRequest()
// Output:
// '{
// error: false,
// category: 'Programming',
// type: 'single',
// joke: 'Programming is 10% science, 20% ingenuity, and 70% getting the ingenuity to work with the science.',
// flags: {
// nsfw: false,
// religious: false,
// political: false,
// racist: false,
// sexist: false
// },
// id: 37,
// lang: 'en'
// }'
// Alternative:
fetch('https://sv443.net/jokeapi/v2/joke/Programming')
.then(response => response.text())
.then(responseText => console.log(responseText))
.catch(err => console.log(err))
// Example no.2:
// Parsing response as a text
async function makeRequest() {
// Use try...catch statement
try {
// Make fetch request
const responseData = await fetch('https://sv443.net/jokeapi/v2/joke/Programming')
// Parsing as JSON happens here:
// Parse the response as a JSON
const responseJSON = await responseData.json()
// Log the JSON
console.log(responseJSON)
}
catch (error) {
// Log any error
console.log(error)
}
}
// Call the makeRequest()
makeRequest()
// Output:
// {
// error: false,
// category: 'Programming',
// type: 'twopart',
// setup: 'How do you generate a random string?',
// delivery: 'Put a Windows user in front of Vim and tell him to exit.',
// flags: {
// nsfw: false,
// religious: false,
// political: false,
// racist: false,
// sexist: false
// },
// id: 129,
// lang: 'en'
// }
// Alternative:
fetch('https://sv443.net/jokeapi/v2/joke/Programming')
.then(response => response.json())
.then(responseJSON => console.log(responseJSON))
.catch(err => console.log(err))
正在处理已经处理的响应
当您使用一种方法处理响应并将其解析为一种格式时,您无法再次处理它并将其解析为另一种格式。如果您将响应解析为文本,则无法再将其解析为 JSON 格式。解析一次响应后,它将被锁定。再次解析将导致 TypeError。
async function makeRequest() {
// Use try...catch statement
try {
// Make fetch request
const responseData = await fetch('https://sv443.net/jokeapi/v2/joke/Programming')
// Parse the response as a text
const responseText = await responseData.text()
// This will not work after the first parsing
// Try to parse the response again as a JSON
const responseJSON = await responseData.json()
// Log the text
console.log(responseText)
// Log the JSON
console.log(responseJSON)
}
catch (error) {
// Log any error
console.log(error)
}
}
// Call the makeRequest()
makeRequest()
// Output:
// TypeError: Failed to execute 'json' on 'Response': body stream is locked
使用 fetch 发起请求
该方法默认的请求类型fetch()是GET。如果您想更改请求类型,可以进行更改。您可以通过可选的配置对象(可将其作为第二个参数传递给该fetch()方法)来更改请求类型。例如,您可以设置method为POST来发出POST请求,等等。
GET 请求
如果按原样使用该fetch()方法并仅提供 URL,它将自动执行GET请求。
// GET request example
async function makeGetRequest() {
// Use try...catch statement
try {
// Make GET fetch request
const responseData = await fetch('https://sv443.net/jokeapi/v2/joke/Programming')
// Parse the response as a JSON
const responseJSON = await responseData.json()
// Log the JSON
console.log(responseJSON)
}
catch (error) {
// Log any error
console.log(error)
}
}
// Call the makeGetRequest()
makeGetRequest()
// Output:
// {
// error: false,
// category: 'Programming',
// type: 'single',
// joke: "Knock knock.
// Who's there?
// Recursion.
// Recursion who?
// Knock knock.",
// flags: {
// nsfw: false,
// religious: false,
// political: false,
// racist: false,
// sexist: false
// },
// id: 182,
// lang: 'en'
// }
// Alternative with promise handler functions:
fetch('https://sv443.net/jokeapi/v2/joke/Programming')
.then(response => response.json())
.then(responseJSON => console.log(responseJSON))
.catch(err => console.log(err))
POST 请求
另一种常见的请求类型是POST。您可以通过更改 on 配置对象来使用 fetch API 发出此类请求method。此对象是您可以传递给 的第二个可选参数fetch()。如果您将 设置method为 ,POST该fetch()方法将执行POST请求。
发出POST请求时,您需要发送一些数据。您可以通过body选项添加这些数据。此选项也包含在配置对象中。此外,您可能还想更改Content-Type。您可以通过headers选项执行此操作。但是,对于简单的请求,POST仅method和body可能就足够了。
// Some data to send
const userData = {
firstName: 'Tom',
lastName: 'Jones',
email: 'tom@jones.ai'
}
// Make POST request
async function makePostRequest() {
// Use try...catch statement
try {
// Make fetch request
const responseData = await fetch('/users/register', {
method: 'POST', // Change the request method
headers: { // Change the Content-Type
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(userData) // Add data you want to send
})
// Parse the response as a JSON
const responseJSON = await responseData.json()
// Log the JSON
console.log(responseJSON)
}
catch (error) {
// Log any error
console.log(error)
}
}
// Call the makePostRequest()
makePostRequest()
// Alternative with promise handler functions:
fetch('/users/register', {
method: 'POST', // Change the request method
headers: { // Change the Content-Type
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(userData) // Add data you want to send
})
.then(response => response.json())
.then(responseJSON => console.log(responseJSON))
.catch(err => console.log(err))
DELETE 请求
当您想要删除某些数据、文件等时,可以发出DELETE请求。发出此类请求所需的语法比 略多GET,但比 少POST。您需要做的是将 选项设置为method。然后,您需要知道正确的 URL 以及要删除的内容。fetch()DELETE
// Make DELETE request
async function makeDeleteRequest() {
// Use try...catch statement
try {
// Make fetch request
const responseData = await fetch('/users/tom', {
method: 'DELETE' // Change the request method
})
// Parse the response as a JSON
const responseJSON = await responseData.json()
// Log the JSON
console.log(responseJSON)
}
catch (error) {
// Log any error
console.log(error)
}
}
// Call the makeRequest()
makeDeleteRequest()
// Alternative with promise handler functions:
fetch('/users/tom', {
method: 'DELETE', // Change the request method
})
.then(response => response.text())
.then(responseText => console.log(responseText))
.catch(err => console.log(err))
PUT 请求
请求类型PUT最常用于更新现有数据或资源。此请求看起来与 几乎相同POST。主要(有时也是唯一的)区别在于method的选项fetch()必须设置为PUT。
// Some data to send to update existing records
const userData = {
firstName: 'Jack',
lastName: 'O\'Brian',
email: 'jack@obrian.co'
}
// Make Put request
async function makePutRequest() {
// Use try...catch statement
try {
// Make fetch request
const responseData = await fetch('/users/jack', {
method: 'PUT', // Change the request method
body: JSON.stringify(userData) // Add data you want to send
})
// Parse the response as a JSON
const responseJSON = await responseData.json()
// Log the JSON
console.log(responseJSON)
}
catch (error) {
// Log any error
console.log(error)
}
}
// Call the makePutRequest()
makePutRequest()
// Alternative with promise handler functions:
fetch('/users/jack', {
method: 'PUT', // Change the request method
body: JSON.stringify(userData) // Add data you want to send
})
.then(response => response.json())
.then(responseJSON => console.log(responseJSON))
.catch(err => console.log(err))
PATCH 请求
这PATCH是我们将要讨论的最后一种使用 fetch API 的请求类型。这种请求与 非常相似PUT。两者的区别在于PUT用于用新版本更新旧版本。这意味着您可以更新所有内容。而PATCH则仅更新部分现有数据,例如用户电子邮件地址。
// Some data to send to update
// only a part of existing records
const userData = {
email: 'jack@obrian.co'
}
// Make PATCH request
async function makePatchRequest() {
// Use try...catch statement
try {
// Make fetch request
const responseData = await fetch('/users/jack', {
method: 'PATCH', // Change the request method
body: JSON.stringify(userData) // Add data you want to send
})
// Parse the response as a JSON
const responseJSON = await responseData.json()
// Log the JSON
console.log(responseJSON)
}
catch (error) {
// Log any error
console.log(error)
}
}
// Call the makePatchRequest()
makePatchRequest()
// Alternative with promise handler functions:
fetch('/users/jack', {
method: 'PATCH', // Change the request method
body: JSON.stringify(userData) // Add data you want to send
})
.then(response => response.json())
.then(responseJSON => console.log(responseJSON))
.catch(err => console.log(err))
关于 Response 对象的说明
我们简要讨论了 Response 对象上可以使用的方法:text()、json()、formData()、blob()、和。这些方法并非 Response 对象的全部。它还包含许多属性。您可能会发现其中一些属性很有用arrayBuffer()。clone()redirect()
一些最有用的属性是statusText、status和ok。statusText是包含 HTTP 状态代码消息的字符串。status是一个数字,用于指定响应的状态代码。当您发出请求并成功时,它将具有status200 的值。
是ok一个布尔值,指定 是否status在 200 到 299 的代码范围内。因此,如果您的请求成功,即 200, 的值ok将为true。此外,还有一个body属性。此属性包含您收到的数据。当您使用某些方法解析响应时,它会与此body属性配合使用。
// Make fetch request
fetch('https://sv443.net/jokeapi/v2/joke/Programming')
.then(response => console.log(response)) // Log the Response object
.catch(err => console.log(err))
// Output:
// {
// body: (...)
// bodyUsed: false
// headers: Headers
// ok: true
// redirected: false
// status: 200
// statusText: ""
// type: "cors"
// url: "https://sv443.net/jokeapi/v2/joke/Programming"
// }
结论:JavaScript Fetch API 入门
JavaScript Fetch API 提供了一种简单易用的请求方式。希望本教程能帮助您了解 Fetch API 是什么以及它的工作原理。也希望我们之前的示例能帮助您理解如何使用这个 API,以及如何成功发出请求以及如何正确处理响应。
鏂囩珷鏉ユ簮锛�https://dev.to/alexdevero/getting-started-with-the-javascript-fetch-api-373k
后端开发教程 - Java、Spring Boot 实战 - msg200.com