本文转载自微信公众号「程序员巴士」,作者Eason。转载本文请联系程序员巴士公众号。
HTTPie 是一个命令行 HTTP 客户端。它的目标是使 CLI 与 Web 服务的交互尽可能人性化。HTTPie 设计用于测试、调试以及通常与 API 和 HTTP 服务器交互。http 和 https 的命令允许创建和发送任意 HTTP 请求。HTTPie 整体采用简单自然的语法,并提供格式化和彩色输出。
主要特点
- 富有表现力和直观的语法
- 格式化和彩色终端输出
- 内置 JSON 支持
- 表格和文件上传
- HTTPS、代理和身份验证
- 任意请求数据
- 自定义标题
- 持续Sessions
- 类似 Wget 的下载
- Linux、macOS、Windows 和 FreeBSD 支持
- 插件
- 文档
- 测试覆盖率
安装
macOS
Homebrew
安装 Homebrew 可以看它的安装教程[1].
安装 httpie
brew update
brew install httpie
升级 httpie
brew update
brew upgrade httpie
Windows
Chocolatey
安装 Chocolatey 可以看它的 安装教程[2].
安装 httpie
choco install httpie
升级 httpie
choco upgrade httpie
Linux
Snapcraft (Linux)
安装 Snapcraft 可以看它的 安装教程[3].
安装 httpie
snap install httpie
升级 httpie
snap refresh httpie
Debian and Ubuntu
也适用于其他 Debian 衍生发行版,如 MX Linux、Linux Mint、deepin、Pop!_OS、KDE neon、Zorin OS、elementary OS、Kubuntu、Devuan、Linux Lite、Peppermint OS、Lubuntu、antiX、Xubuntu 等。
安装 httpie
apt update
apt install httpie
升级 httpie
apt update
apt upgrade httpie
FreeBSD
安装 httpie
pkg install www/py-httpie
升级 httpie
pkg upgrade www/py-httpie
安装测试版本
大家还可以直接从masterGitHub 上的分支安装最新的未发布开发版本。它是未来稳定版本的正在进行中的工作,因此体验可能不会那么顺利。
大家可以使用以下命令在 Linux、macOS、Windows 或 FreeBSD 上安装pip:
python -m pip install --upgrade https://github.com/httpie/httpie/archive/master.tar.gz
或者在 macOS 和 Linux 上,使用 Homebrew:
brew uninstall --force httpie
brew install --HEAD httpie
甚至在 macOS 和 Linux 上,使用 Snapcraft:
snap remove httpie
snap install httpie --edge
验证是否拥有带有后缀的当前开发版本标识符.dev0,例如:
http --version
#3.0.3.dev0
用法
Hello World:
https httpie.io/hello
获取用法:
http [flags] [METHOD] URL [ITEM [ITEM]]
http --help
举例
自定义HTTP 方法、HTTP Header和JSON数据:
http PUT pie.dev/put X-API-Token:123 name=John
提交 forms:
http -f POST pie.dev/post hello=World
查看使用输出选项之一发送的请求:
http -v pie.dev/get
在不发送的情况下通过使用离线模式构建和打印请求:
http --offline pie.dev/post hello=offline
使用重定向上传文件:
http pie.dev/post < files/data.json
下载文件并通过重定向输出保存:
http pie.dev/image/png > image.png
使用命名Sessions使对同一主机的请求之间的通信的某些方面保持持久:
http --session=logged-in -a username:password pie.dev/get API-Key:123
http --session=logged-in pie.dev/headers
设置自定义Host Header以解决丢失的 DNS 记录:
http localhost:8000 Host:example.com
HTTP方法
HTTP 方法的名称就在 URL 参数之前:
http DELETE pie.dev/delete
这看起来与发送的实际相似Request-Line:
DELETE /delete HTTP/1.1
除了标准方法(GET、POST、HEAD、PUT、PATCH、DELETE等)之外,还可以使用自定义方法名称,例如:
http AHOY pie.dev/post
对于请求方法可以包含正文没有任何限制,发送一个空POST请求:
http POST pie.dev/post
还可以发出GET包含正文的请求:
http GET pie.dev/get hello=world
可选GET和POST
该METHOD参数是可选的,当你不指定它时,HTTPie 默认为:
- GET: 对于没有正文的请求
- POST: 对于带有正文的请求
这里我们没有指定任何请求数据,所以两个命令将发送相同的GET请求:
http GET pie.dev/get
http pie.dev/get
另一方面,我们可以通过两个命令将发出相同的POST请求:
http pie.dev/post hello=world
请求网址
HTTPie 执行请求所需的唯一信息是 URL。
默认方案是http://并且可以从参数中省略:
http example.org
#→ http://example.org
HTTPie 还安装了一个https可执行文件,其中默认方案是https://:
https example.org
#→ https://example.org
当把 URL 粘贴到终端时,甚至可以保留://URL 参数中的位,以将 URL 快速转换为 HTTPie 调用,只需在协议名称后添加一个空格即可。
https ://example.org #→ https://example.org
网址快捷方式localhost
支持类似 curl 的 localhost 简写。这意味着,例如,:3000将扩展为http://localhost:3000 如果省略端口,则假定端口 80。
http :/foo
GET /foo HTTP/1.1
Host: localhost
http :3000/bar
GET /bar HTTP/1.1
Host: localhost:3000
http :
GET / HTTP/1.1
Host: localhost
JSON
JSON 是现代 Web 服务的通用语,也是HTTPie 默认使用的隐式内容类型。
简单的例子:
http PUT pie.dev/put name=John email=john@example.org
PUT / HTTP/1.1
Accept: application/json, */*;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Host: pie.dev
{
"name": "John",
"email": "john@example.org"
}
默认行为
如果命令中包含一些数据请求项,则默认将它们序列化为 JSON 对象。HTTPie 还自动设置以下Header,这两个Header都可以被覆盖:
Content-Type : application/json
Accept : application/json, /;q=0.5
显式 JSON
无论是否正在发送数据,都可以使用--json, -j显式设置Accept为(这是通过通常的Header符号设置Header的快捷方式:) 。此外,即使响应不正确或未知,HTTPie 也会尝试检测 JSON 响应。application/jsonhttp url Accept:'application/json, /;q=0.5'Content-Typetext/plain
非字符串 JSON 字段
非字符串 JSON 字段使用:=分隔符,它允许将任意 JSON 数据嵌入到生成的 JSON 对象中。此外,文本和原始 JSON 文件也可以使用=@和嵌入到字段中:=@:
http PUT pie.dev/put \
name=John \ # String (default)
age:=29 \ # Raw JSON — Number
married:=false \ # Raw JSON — Boolean
hobbies:='["http", "pies"]' \ # Raw JSON — Array
favorite:='{"tool": "HTTPie"}' \ # Raw JSON — Object
bookmarks:=@files/data.json \ # Embed JSON file
description=@files/text.txt # Embed text file
PUT /person/1 HTTP/1.1
Accept: application/json, */*;q=0.5
Content-Type: application/json
Host: pie.dev
{
"age": 29,
"hobbies": [
"http",
"pies"
],
"description": "John is a nice guy who likes pies.",
"married": false,
"name": "John",
"favorite": {
"tool": "HTTPie"
},
"bookmarks": {
"HTTPie": "https://httpie.org",
}
}
:=/:=@语法是 JSON 特定的。大家可以将请求切换为--formor --multipart,并且字符串、浮点数和数字值将继续被序列化(作为字符串形式的值)。但是,其他 JSON 类型不允许使用--form或--multipart。
形式
提交表单与发送JSON请求非常相似。通常唯一的区别是添加--form, -f选项,它确保数据字段被序列化为,并Content-Type设置为application/x-www-form-urlencoded; charset=utf-8. 可以通过配置文件使表单数据成为隐式内容类型而不是 JSON。
常规表格
http --form POST pie.dev/post name='John Smith'
POST /post HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
name=John+Smith
文件上传表格
如果存在一个或多个文件字段,则序列化和内容类型为multipart/form-data:
http -f POST pie.dev/post name='John Smith' cv@~/files/data.xml
上面的请求与提交以下 HTML 表单相同:
<form enctype="multipart/form-data" method="post" action="http://example.com/jobs">
<input type="text" name="name" />
<input type="file" name="cv" />
</form>
请注意,@它用于模拟文件上传表单字段,而=@只是将文件内容嵌入为常规文本字段值。
上传文件时,它们的内容类型是从文件名中推断出来的。大家可以手动覆盖推断的内容类型:
http -f POST pie.dev/post name='John Smith' cv@'~/files/data.bin;type=application/pdf'
multipart/form-data即使没有任何文件也要执行请求,请使用--multipart代替--form:
http --multipart --offline example.org hello=world
POST / HTTP/1.1
Content-Length: 129
Content-Type: multipart/form-data; boundary=c31279ab254f40aeb06df32b433cbccb
Host: example.org
--c31279ab254f40aeb06df32b433cbccb
Content-Disposition: form-data; name="hello"
world
--c31279ab254f40aeb06df32b433cbccb--
文件上传总是流式传输以避免大文件的内存问题。
默认情况下,HTTPie 使用随机唯一字符串作为多部分边界,但大家可以使用它--boundary来指定自定义字符串:
http --form --multipart --offline example.org hello=world Content-Type:multipart/letter
POST / HTTP/1.1
Content-Length: 129
Content-Type: multipart/letter; boundary=c31279ab254f40aeb06df32b433cbccb
Host: example.org
--c31279ab254f40aeb06df32b433cbccb
Content-Disposition: form-data; name="hello"
world
--c31279ab254f40aeb06df32b433cbccb--
如果指定自定义Content-Type Header而不包括边界位,HTTPie 将自动将边界值(显式指定或自动生成)添加到 Headers:
http --form --multipart --offline example.org hello=world Content-Type:multipart/letter
POST / HTTP/1.1
Content-Length: 129
Content-Type: multipart/letter; boundary=c31279ab254f40aeb06df32b433cbccb
Host: example.org
--c31279ab254f40aeb06df32b433cbccb
Content-Disposition: form-data; name="hello"
world
--c31279ab254f40aeb06df32b433cbccb--
HTTP Headers
要设置自定义 Headers,可以通过使用以下Header:Value符号:
http pie.dev/headers User-Agent:Bacon/1.0 'Cookie:valued-visitor=yes;foo=bar' \
X-Foo:Bar Referer:https://httpie.org/
GET /headers HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Cookie: valued-visitor=yes;foo=bar
Host: pie.dev
Referer: https://httpie.org/
User-Agent: Bacon/1.0
X-Foo: Bar
默认请求headers
HTTPie 设置了几个默认Header:
GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
User-Agent: HTTPie/<version>
Host: <taken-from-URL>
其中任何一个都可以被覆盖,其中一些可以取消设置(见下文)。
具有相同名称的多个Header Value
如果请求是使用共享相同名称的多个Header发送的,则 HTTPie 将单独发送它们。
http --offline example.org Cookie:one Cookie:two
GET / HTTP/1.1
Cookie: one
Cookie: two
也可以传递单个header value pair,其中值是Header Value的逗号分隔列表。然后客户端会将其作为单个header发送。
http --offline example.org Numbers:one,two
GET / HTTP/1.1
Numbers: one,two
另外,如果当前Sessions包含任何header,则它们将在发送请求时被单独的命令覆盖,而不是被连接在一起。
限制响应Header
这些--max-headers=n选项允许控制 HTTPie 在放弃之前读取的Header数量(默认值0,即没有限制)。
http --max-headers=100 pie.dev/get
Cookies
HTTP 客户端将 cookie 作为常规HTTP Header发送到服务器。这意味着,HTTPie 不提供任何用于指定 cookie 的特殊语法——使用通常的Header:Value符号:
发送一个 cookie:
http pie.dev/cookies Cookie:sessionid=foo
GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: sessionid=foo
Host: pie.dev
User-Agent: HTTPie/0.9.9
发送多个 cookie(注意:header被引用以防止 shell 解释;):
http pie.dev/cookies 'Cookie:sessionid=foo;another-cookie=bar'
GET / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Cookie: sessionid=foo;another-cookie=bar
Host: pie.dev
User-Agent: HTTPie/0.9.9
HTTPS
服务器 SSL 证书验证
跳过主机的 SSL 证书验证,可以通过--verify=no(默认为yes):
http --verify=no https://pie.dev/get
自定义 CA 包
大家还可以使用--verify=设置自定义 CA 包路径:
http --verify=/ssl/custom_ca_bundle https://example.org
客户端 SSL 证书
要将客户端证书用于 SSL 通信,可以使用以下命令传递证书文件的路径--cert:
http --cert=client.pem https://example.org
如果私钥不包含在证书文件中,大家可以通过以下方式传递密钥文件的路径--cert-key:
http --cert=client.crt --cert-key=client.key https://example.org
SSL 版本
使用该--ssl=选项指定要使用的所需协议版本。这将默认为 SSL v2.3,它将协商服务器和安装的 OpenSSL 支持的最高协议。可用的协议是ssl2.3, ssl3, tls1, tls1.1, tls1.2, tls1.3. (实际可用的协议集可能因 OpenSSL 安装而异。)
#Specify the vulnerable SSL v3 protocol to talk to an outdated server:
http --ssl=ssl3 https://vulnerable.example.org
SSL 密码
可以使用 指定可用的密码--ciphers。它应该是OpenSSL 密码列表格式的字符串。
#Specify the vulnerable SSL v3 protocol to talk to an outdated server:
http --ssl=ssl3 https://vulnerable.example.org
Sessions
默认情况下,HTTPie 发出的每个请求都完全独立于同一主机之前的任何请求。
但是,HTTPie 也通过该--session=SESSION_NAME_OR_PATH选项支持持久Sessions。在Sessions中,自定义HTTP Header Content-(以or开头的Header除外If-)、身份验证和cookie(手动指定或由服务器发送)在对同一主机的请求之间持续存在。
#Create a new session:
http --session=./session.json pie.dev/headers API-Token:123
#Inspect / edit the generated session file: cat session.json
#Re-use the existing session — the API-Token header will be set:
http --session=./session.json pie.dev/headers
所有Session数据,包括凭据、提示密码、cookie 数据和自定义header都以纯文本形式存储。这意味着Sessions文件也可以在文本编辑器中手动创建和编辑——它们是常规的 JSON。这也意味着任何有权访问Session文件的人都可以读取它们。
命名Sessions
大家可以为每个主机创建一个或多个命名Sessions。例如,可以通过以下方式创建一个名为user1for的新Sessions pie.dev:
http --session=user1 -a user1:password pie.dev/get X-Foo:Bar
user1从现在开始,可以通过名称 ( )来引用Sessions。当选择再次使用Sessions时,将自动设置所有先前指定的身份验证或 HTTP header:
http --session=user1 pie.dev/get
要创建或重用不同的Sessions,只需指定不同的名称:
http --session=user2 -a user2:password pie.dev/get X-Bar:Foo
命名Sessions的数据存储在配置sessions目录子目录内的 JSON 文件中,通常(在 Windows 上)。~/.config/httpie/sessions//.json%APPDATA%\httpie\sessions.json
如果大家在 Unix 机器上执行了上述命令,应该能够使用以下命令列出生成的Sessions文件:
ls -l ~/.config/httpie/sessions/pie.dev
匿名Session
可以直接指定Sessions文件的路径,而不是为其命名。这允许跨多个主机重复使用Session:
#Create a session:
http --session=/tmp/session.json example.org
#Use the session to make a request to another host:
http --session=/tmp/session.json admin.example.org
#You can also refer to a previously created named session:
http --session=~/.config/httpie/sessions/another.example.org/test.json example.org
在创建匿名Sessions时,请记住始终包含至少一个/,即使Sessions文件位于当前目录中(即--session=./session.json,而不是只是--session=session.json),否则 HTTPie 会采用命名Sessions。
只读Sessions
要在创建后使用原始Sessions文件而不从请求/响应交换中更新它,请指定Sessions名称 via --session-read-only=SESSION_NAME_OR_PATH。
#If the session file doesn’t exist, then it is created:
http --session-read-only=./ro-session.json pie.dev/headers Custom-Header:orig-value
#But it is not updated:
http --session-read-only=./ro-session.json pie.dev/headers Custom-Header:new-value
参考资料
[1]安装教程: https://docs.brew.sh/Installation
[2]安装教程: https://chocolatey.org/install[3]安装教程: https://snapcraft.io/docs/installing-snapd