在Javascript社区,关于哪个HTTP客户端在易用性方面是最好的,已经争论了很久,在这些客户端中,Axios对很多开发者来说绝对是排名前三的。本文将告诉你如何使用axios进行HTTP请求,并在请求中传递HTTP标头信息。我们还将仔细研究HTTP标头的工作原理以及为什么它们很重要。
为什么要使用axios而不是node-fetch?
node-fetch
是Fetch
API规范的服务器端实现,它试图标准化HTTP请求的含义和所涉及的各种术语的定义。 axios是一个类似node-fetch
的HTTP客户端,但由于axios
已经存在了很长时间,很多开发人员倾向于使用axios
而不是fetch
。有几个有趣的原因可以说明为什么你可能想使用axios
而不是node-fetch
。
- 有用的工具,如创建拦截器或一个实例。虽然可以自己编写代码来创建拦截器或使用
node-fetch
的可重用实例,但与使用axios
提供的内置功能相比,这或多或少是一种额外的努力。 - 中止请求和超时:
node-fetch
和浏览器fetch
试图通过使用所谓的AbortController
来解决中止请求(因此取消了一个承诺)。与axios
提供的API相比,使用AbortController
是相当啰嗦的。而且,在使用node-fetch
时,必须手工实现超时。 - 自动数据转换–
axios
将您的POST
请求体转换为字符串,例如,无需明确告知,这与node-fetch
不同。
用axios发送HTTP标头
axios
提供了一个与node-fetch
非常相似的发送HTTP标头的API。在axios
中,有两种方法可以进行HTTP请求,一种是向axios()
提供一个config
对象。第二种是使用axios
提供的请求方法别名,它遵循axios.<method>()
的一般语法,你可以将一个url
和一个config
对象作为参数传给它。后者往往被更多地使用,因为它很直观。
为了本教程的目的,我们将利用JSON占位符API。
const axios = require("axios"); const config = { headers: { "Referer": "https://www.scrapingbee.com/", "Referrer-Policy": "strict-origin-when-cross-origin" }, }; axios .get("https://jsonplaceholder.typicode.com/todos/1", config) .then((response) => console.log(response.data)) .catch((error) => console.log(error.response));
调用axios.get
或axios
返回一个承诺,该承诺解析为一个响应对象,该对象的模式是这样的。如果由于某种原因,出现了某种错误,那么承诺将拒绝一个包含响应
属性的错误
对象,该对象同样遵循前面提到的模式。
配置
对象的模式是这样的,它允许你做的远不止是发送HTTP标头信息。你可能看到,我们使用了Referer
和Referer-Policy
标头信息。像Referer
这样的标头信息对于实现那些依赖于知道流量来自何处的功能是必不可少的,比如日志或分析。
然而,请注意,虽然Referer
(是的,它没有双R
)可以在你发送敏感数据的情况下引入隐私风险,在Referer URL旁边。解决这类问题的一个非常好的方法是使用Referer-Policy
,当然也可以合理地设计你的应用程序。在这里阅读更多关于Referer
和Referer-Policy
的信息。
与发送HTTP GET请求类似,如果你想发送例如POST
请求,你可以用POST数据和config
对象使用相应的请求方法别名,或者直接将配置
对象传递给axios()
,方法
属性设置为POST
。
const axios = require("axios"); const newPost = { title: "ScrapingBee is awesome!", body: "Learning to set HTTP headers...", userId: 1, }; const config = { headers: { "Content-type": "application/json; charset=UTF-8", }, }; axios .post( "https://jsonplaceholder.typicode.com/posts", newPost, config ) .then((response) => console.log(response.data)) .catch((error) => console.log(error.response)); [文中代码源自Scrapingbee]
与HTTP请求一起发送适当的HTTP标头是很重要的,有时也是一种安全要求,因为这些标头对发送到服务器的内容提供了关键的洞察力,有助于正确识别和提取HTTP请求中的信息。
其中一个例子是发送正确的 “Content-Type "
标头。例如,浏览器会看一下Content-Type
标头,以知道到底该如何处理收到的数据。你可以在这里阅读更多关于Content-Type
的重要性以及浏览器如何发展以应对与之相关的安全问题。
究竟什么是HTTP标头?
HTTP标头是非常简单的附加信息,你将其与你的HTTP请求或响应一起传递,以便客户端或接收它的服务器能够正确处理请求或响应。有不同类型的HTTP标头,最常见的方法是通过观察它们的预期环境来分组。
- 一般头文件– 请求和响应都有的头文件,与发送或接收的实际数据无关。
- 请求头– 包含关于请求的客户端的关键信息,以及关于正在请求的资源的信息。
- 响应标题– 包含任何与发送数据的地点和内容有关的额外信息。
- 实体头文件– 包含有关资源的信息。
你可以在MDN文档中阅读更多关于HTTP标头、其他分类方法以及现有的各种HTTP标头的信息。
使你的HTTP请求看起来像浏览器
在爬取网络的过程中,当务之急是使你的请求看起来尽可能真实和不像机器人。要做到这一点,最常见、最简单、最有效的方法之一是利用用户代理
头。User-Agent
头是一个字符串,它决定了操作系统、供应商和用户代理本身。用户代理可以被简单地认为是一个你用来执行HTTP请求的应用程序。
一些最常见的用户代理是。
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36
Mozilla/5.0 (iPhone; CPU iPhone OS 13_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Mobile/15E148 Safari/604.1
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0
你可以在这里看一下更详细的User-Agent标头信息列表。然而,请记住,不要爬取该列表,或者至少如果你这样做,要确保不滥用该服务,因为该网站指出,他们曾有过不正当的机器人写作问题。
虽然用户代理是模拟实际浏览器的最简单方法之一,但如果你想增加冒充实际浏览器的机会,通常会有更多的工作。再来几个标题,比如。
Accept-Language
头–声明提出请求的客户或服务器能够理解什么语言。Accept-Encoding
头 – 声明对内容使用哪种压缩算法。
可以真正提高你的机会。
在发送HTTP请求的同时发送这样的标头信息,可以使请求更有可能被当作一个真实的浏览器发出的真实请求。然而,随着像浏览器指纹这样的技术一天天被广泛采用,你的努力可能就不够了。然而,浏览器指纹识别在某种程度上也依赖于头文件,但也利用cookies和画布(称为画布指纹识别)来独特地识别用户。
如果你比较一下用Puppeteer提交表单和自己用Axios这样的HTTP客户端做请求的区别,你会很快意识到只用HTTP客户端是多么高效。
总 结
了解如何利用各种可用的标头信息的正确组合,对于使用Axios这样的HTTP客户端发送类似浏览器的HTTP请求至关重要。
- Axios Github Repo– 包含文档和大量的例子,说明如何很好地利用axios提供的各种API,使你的生活更轻松。
- JSON placeholder 文档 – JSON placeholder 是一个完美的服务,可以测试你的HTTP请求,而不需要建立你自己的服务器。