如何用Axios掌握HTTP请求
了解如何使用Axios处理你的所有HTTP请求
Axios是Javascript开发者中最受欢迎的HTTP客户端之一。它被用来从客户端和服务器端发送HTTP请求,尤其是AJAX请求。
现在,在开发动态网络应用时,从Javascript端发送HTTP请求几乎是一种必需品。Axios通过在Javascript的XMLHttpRequest接口上提供一个易于使用的抽象,以及一些用户友好的功能和配置选项,简化了这项任务。
在本教程中,我们将通过代码实例和简化的解释,介绍你所需要知道的关于用Axios发送HTTP请求的一切。
让我们以这个问题开始我们的介绍。
你为什么要选择Axios?
为了回答这个问题,让我们来看看开发人员可用的Axios替代品。
Javascript提供了一个内置接口,XMLHttpRequest ,用于处理HTTP请求。然而,用这个接口发送请求不是很直接,需要写太多的代码行。
如果你使用过JQuery,你一定熟悉$_ajax 功能。它在XMLHttpRequest接口上提供了一个更简单、更容易使用的抽象,我们可以用更少的代码行来发送HTTP请求。但在过去的几年里,由于像JQuery这样的库已经过时了,开发者需要一个原生的Javascript解决方案来创建HTTP请求。
现在,Fetch API和Axios是本地Javascript中最流行的两个解决方案,用于发送这些请求。然而,与Fetch API相比,Axios有优势,因为它为开发者提供了一些独特的功能。这里我们列出了其中的几个:
- 支持对请求和响应的拦截
- 取消请求的能力
- 支持旧的浏览器(Internet Explorer 11)。
- JSON数据的自动转换
- 对XSRF保护的客户端支持
由于其强大的功能集,现在开发者开始喜欢用Axios而不是Fetch API来发送HTTP请求。
安装Axios
你可以在前端和后端都安装和使用Axios。如果你使用npm这样的包管理器,安装很简单:
npm install axios
如果你使用的是内容交付网络(CDN),将Axios脚本嵌入到HTML中:
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
或者:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
用Axios发送HTTP请求
用Axios发送HTTP请求,就像把一个包含所有配置选项和数据的对象传递给axios() 函数一样简单:
axios({
method: "post",
url: "/users",
data: {
username: "sam123",
firstname: "sam",
lastname: "smith"
}
});
让我们仔细看一下这里使用的配置选项:
- 方法:请求必须使用的HTTP方法
- url:请求必须发送到的服务器的URL
- 数据:在POST、PUT和PATCH请求的情况下,用这个选项提供的数据会在HTTP请求的正文中发送。
要查看Axios请求函数的所有配置选项,请参考其官方文档。
专用的请求函数
除了通用的axios() ,Axios还提供了专门的函数来简化发送不同类型的请求。下面是这些函数的列表:
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])
例如,我们可以使用axios.post() 函数来发送POST请求,而不是通过设置方法为 "post "来使用axios() 函数:
axios.post("/users", {
username: "sam123",
firstname: "sam",
lastname: "smith"
});
我们可以用类似的方式使用axios.get() 函数来发送GET请求:
axios.get("/users", {
params: {
firstname: "sam"
}
});
params配置选项是用来设置URL中的查询参数。
发送多个并发请求
我们可以使用Axios来并发发送多个请求。为了实现这一点,我们必须将一个请求调用数组传递给Promise.all() 函数:
Promise.all([
axios.get("/users/sam123"),
axios.get("/users/sam123/comments")
]);
用Axios处理响应
当我们向一个远程服务器发送HTTP请求时,我们会从该服务器收到一个包含某些信息的响应。我们可以使用Axios检索这个响应。
根据Axios文档,返回的响应包含以下信息:
{
// `data` is the response that was provided by the server
data: {},
// `status` is the HTTP status code from the server response
status: 200,
// `statusText` is the HTTP status message from the server response
statusText: 'OK',
// `headers` the HTTP headers that the server responded with
// All header names are lower cased and can be accessed using the bracket notation.
// Example: `response.headers['content-type']`
headers: {},
// `config` is the config that was provided to `axios` for the request
config: {},
// `request` is the request that generated this response
// It is the last ClientRequest instance in node.js (in redirects)
// and an XMLHttpRequest instance in the browser
request: {}
}
由于Axios是基于承诺的,所以响应会以承诺的形式返回。因此,我们需要使用then() 和catch() 函数来检索响应,如果有错误,则捕捉错误。
让我们看看我们如何处理POST请求返回的响应:
axios.post("/users", {
username: "sam123",
firstname: "sam",
lastname: "smith"
})
.then(response => {
console.log(response);
console.log(response.data);
console.log(response.data.userId);
console.log(response.status);
console.log(response.statusText);
})
.catch(error => {
console.log(error.message);
});
使用async/await
我们也可以使用async/await来发送HTTP请求并处理响应,而不是使用承诺:
async function getUserData() {
try {
const response = await axios.get("/users/sam123");
console.log(response);
}
catch (error) {
console.log(error);
}
}
处理来自并发请求的响应
在上一节中,我们使用Promise.all() 方法来发送多个并发的请求。当所有传递给该方法的请求完成后,它返回一个包含每个请求的响应对象的单一承诺。我们可以使用传递给该方法的数组中每个请求的索引来分离响应:
Promise.all([
axios.get("/users/sam123"),
axios.get("/users/sam123/comments")
])
.then(response => {
const user = response[0].data
const comments = response[1].data
})
.catch(error => {
console.log(error);
});
处理错误
如果在用Axios发送HTTP请求时发生错误,返回的错误对象包含特定的信息,以帮助我们找出错误发生的确切位置。正如你在下面的例子中看到的,有三个地方可能发生错误:
axios.post("/users", {
username: "sam123",
firstname: "sam",
lastname: "smith"
})
.then(response => {
console.log(response);
})
.catch(error => {
if (error.response) {
//The response status is an error code
console.log(error.response.status);
}
else if (error.request) {
//Response not received though the request was sent
console.log(error.request);
}
else {
//An error occurred when setting up the request
console.log(error.message);
}
});
有了Axios提供的这些信息,你就可以根据错误发生的位置来适当地处理错误。
用POST请求发送数据
当用Axios发送POST请求(也包括PUT和PATCH请求)时,请注意我们是如何将一个普通的Javascript对象作为数据传递的。Axios默认将这些Javascript数据转换为JSON。它还将 "content-type "标头设置为 "application/json"。
然而,如果你传递一个序列化的JSON对象作为数据,Axios会将内容类型视为 "application/x-www-form-urlencoded"(表单编码的请求体)。如果预期的内容类型是JSON,你必须使用 "头文件 "配置选项手动设置头文件:
const data = JSON.stringify({name: "sam"});
const options = {
headers: {"content-type": "application/json"}
}
axios.post("/users", data, options);
如果你想发送除JSON以外的任何其他类型的数据,你必须明确地转换数据并适当地设置内容类型头。Axios提供了两个配置选项:transformRequest 和transformResponse ,你可以在发送请求和接收响应之前分别进行这种转换。
转换数据
让我们看看在发送请求时如何使用这两个配置选项:
axios({
method: "post",
url: "users/sam123",
data: {
username: "sam123",
firstname: "sam",
lastname: "smith"
},
transformRequest: [(data, headers) => {
//Transform request data as you prefer
return data;
}],
transformResponse: [(data) => {
//Transform the response data as you prefer
return data;
}]
});
为请求设置自定义标头
你可以很容易地为你用Axios发送的请求设置自定义头信息。你只需要向你使用的请求方法传递一个包含自定义头信息的对象:
const options = {
headers: {"X-Custom-Header": "value"}
}
axios.get("users/sam123", options);
设置配置默认值
你可以设置默认的配置选项,使其适用于你使用Axios发送的每个请求。这样一来,你就不必重复设置所有请求中通用的选项。
例如,如果你想设置每个请求使用的基本URL或授权头,可以很容易实现,如下例所示:
axios.defaults.baseURL = "https://example.com";
axios.defaults.headers.common["Authorization"] = AUTH_TOKEN
设置实例的配置默认值
有时,由于我们发送的请求不同,为每个HTTP请求设置默认配置变得不现实:我们可能向两个不同的API发送请求,或者根据用户权限使用不同的授权令牌。
在这种情况下,虽然我们无法找到每个请求都有的配置选项,但我们可能会找到不同请求组的共同选项。Axios为我们提供了一种为这些不同组别分别设置默认配置的方法。
这就是通过创建实例。
我们可以创建单独的实例并为每个实例设置默认配置。然后,我们可以使用这个实例对象来发送请求,而不是axios对象:
//Create new instance
const instance = axios.create();
//Set config defaults for the instance
instance.defaults.baseURL = "https://example.com";
instance.defaults.headers.common["Authorization"] = AUTH_TOKEN;
//Send requests using the created instance
instance.get("/users", {
params: {
firstname: "sam"
}
});
拦截请求
HTTP请求拦截是Axios中最有趣的功能之一。它允许你拦截由你的程序发送的请求和收到的请求,并在操作完成前执行一些常见任务。这个功能简化了与HTTP请求相关的后台任务的处理,如日志、认证和授权。
为请求或响应定义一个拦截器是一个简单的任务:
axios.intercept.request.use(config => {
//Intercept the request and do something before it is sent
console.log("Request sent");
return config;
}, error => {
return Promise.reject(error);
});
axios.get("/users/sam123")
.then(response => {
console.log(response.data);
});
在这里,配置对象正是我们传递给axios函数的配置对象或其别名之一。所以拦截器可以完全访问请求配置和它的数据。
设置完请求拦截器后,每次程序发送新的请求时,"请求已发送 "的信息就会被记录到控制台。
我们可以用类似的方法设置一个响应拦截器:
axios.intercept.response.use(config => {
//Intercept the response and do something when it is received
console.log("Response recieved");
return config;
}, error => {
return Promise.reject(error);
});
axios.get("/users/sam123")
.then(response => {
console.log(response.data);
});
现在,每当收到一个响应时,"收到响应 "的消息就会被记录到控制台中。
我们也可以为实例而不是axios对象定义拦截器:
instance.intercept.request.use(config => {
//Intercept the request and do something before it is sent
console.log("Request sent");
return config;
}, error => {
return Promise.reject(error);
});
取消请求
Axios提供的另一个有趣的功能是我们可以随时取消请求。
在Web开发中,有些情况下我们可能会发现远程服务器对我们的请求的响应已经不再重要。在这种情况下,我们可以通过简单地取消请求来节省系统资源。而Axios为我们提供了一种方法来做到这一点。
如果你想取消某个请求,它应该有一个取消令牌,这个令牌是在创建请求的时候创建的。我们可以随时使用这个令牌来取消请求。
这就是取消过程的实现方式:
const cancelToken = axios.cancelToken;
const source = cancelToken.source();
axios.get("/users/sam123", {
cancelToken: source.token //create cancel token
})
.then(response => {
console.log(response.data);
})
.catch(thrown => {
if (axios.isCancel(thrown)) {
console.log("Request cancelled", thrown.message);
}
else {
//handle the error
}
})
//Cancel the request
source.cancel("Request cancelled by the user");
值得注意的是,我们可以使用一个单一的源对象来同时取消几个请求。当source.cancel被调用时,所有使用给定源创建的取消令牌的请求都会被取消。
防范XSRF攻击
跨站请求伪造(XSRF)是一种被攻击者用来渗透到Web应用程序并执行恶意任务的技术。在这些攻击中,攻击者伪装成受信任的用户,欺骗应用程序执行对他们有利的操作。
这可能会损害用户的隐私和安全,如果用户有高级权限,甚至会导致攻击者获得对整个系统的访问。
Axios提供了一种方法,通过在创建请求时嵌入额外的认证信息来防止这种攻击。这就是它的实现方式:
const options = {
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
};
axios.post("/users", options);
总结
在本教程中,我们讨论了作为一个Web开发者需要知道的关于用Axios发送HTTP请求的一切。正如你所看到的,Axios使处理HTTP请求和响应的任务变得异常简单。
它提供了许多配置选项,可以根据我们的需要改变默认行为。它提供了许多方法来简化发送HTTP请求的任务。在Axios的帮助下,你可以在你的应用程序的后端和前端实现HTTP请求发送功能,速度比你想象的要快。
所以,如果你还没有,请将Axios添加到你的Javascript库中,用它轻松实现你的HTTP请求发送任务。