IntelliJ IDEA *.http 文件完全指南
适用版本 :IntelliJ IDEA Ultimate 2017.3+(含 2024/2025/2026 新版 HTTP Client)
同类支持 :WebStorm、PyCharm Professional、GoLand、Rider 等 JetBrains 商业版
最后更新:2026-08
目录
- [第一章 功能介绍](#第一章 功能介绍)
- [第二章 语法](#第二章 语法)
- [第三章 使用方式](#第三章 使用方式)
- [第四章 与 Postman 对比](#第四章 与 Postman 对比)
- 附录
第一章 功能介绍
1.1 什么是 *.http 文件
*.http(也支持 *.rest)是 JetBrains HTTP Client 的纯文本请求脚本文件。你可以在 IDE 里直接编写 HTTP / gRPC / GraphQL / WebSocket 请求,点击运行即可查看响应,无需打开 Postman、curl 或浏览器。
1.2 核心特性
| 特性 | 说明 |
|---|---|
| 纯文本 | 可进 Git、可 Code Review、可团队共享 |
| 多请求支持 | 一个文件可放多个请求,用 ### 分隔 |
| 变量系统 | 支持就地变量、环境文件、动态变量、脚本变量 |
| 多环境切换 | dev / staging / prod 一键切换 |
| 脚本能力 | 预请求脚本 + 响应处理脚本(JavaScript) |
| 断言测试 | 内置 client.test / client.assert,可当轻量接口测试 |
| CLI 支持 | 独立命令行工具 ijhttp,可接入 CI/CD |
| 协议丰富 | HTTP/1.1、HTTP/2、WebSocket、gRPC、GraphQL |
| 代码生成 | 可从 Spring Controller、OpenAPI 一键生成请求 |
1.3 两种文件类型
| 类型 | 创建方式 | 特点 | 适用场景 |
|---|---|---|---|
| Scratch HTTP Request | Ctrl+Alt+Shift+Insert → HTTP Request |
不进项目,IDE 自动写回响应链接 | 临时调试、快速验证 |
Physical *.http |
File → New → HTTP Request |
落在项目目录,不被动修改 | 接口文档、回归脚本、团队共享 |
1.4 与其他工具的定位差异
Postman → GUI 驱动,适合手工探索与团队协作平台
cURL → 命令行,适合脚本与管道
IDEA *.http → 代码化、版本化、IDE 内闭环,适合开发者日常 + CI
第二章 语法
2.1 请求基本结构
http
# 注释可用 # 或 //
METHOD URL HTTP/1.1 # HTTP 版本可省略,默认 HTTP/1.1
Header-Name: Header-Value
请求体(与 Header 之间必须空一行)
规则要点:
- 第一行:
GET https://...或POST {``{host}}/path,方法建议大写 - Header 行顶格写,
Key: Value格式 - Header 与 Body 之间必须空一行
- 支持所有标准方法:
GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS - 也支持自定义方法(如
PROPFIND)
2.2 请求分隔符
http
### 请求名称(注释)
GET https://httpbin.org/get
### 另一个请求
POST https://httpbin.org/post
Content-Type: application/json
{"key": "value"}
### 后面可跟文字作为请求名称,在 Run 窗口中显示。
2.3 变量语法
2.3.1 引用变量
所有变量统一用 {``{varName}} 引用。
2.3.2 就地变量(文件内生效)
写在请求块上方或文件顶部:
http
@host = https://httpbin.org
@port = 443
@token = abc123
GET {{host}}/headers
Authorization: Bearer {{token}}
2.3.3 环境文件变量
http-client.env.json(可提交 Git):
json
{
"dev": {
"baseUrl": "http://localhost:8080",
"token": "dev-token"
},
"staging": {
"baseUrl": "https://staging.example.com",
"token": "staging-token"
},
"prod": {
"baseUrl": "https://api.example.com",
"token": "prod-token"
}
}
http-client.private.env.json(不提交 Git,优先级更高):
json
{
"dev": {
"password": "secret-dev",
"apiKey": "private-key-dev"
},
"prod": {
"password": "secret-prod",
"apiKey": "private-key-prod"
}
}
优先级 :private env > public env > 文件
@var> 请求内变量
2.3.4 动态变量(内置函数)
| 变量 | 说明 | 示例 |
|---|---|---|
{``{$uuid()}} |
生成 UUID v4 | ?id={``{$uuid()}} |
{``{$timestamp()}} |
当前 Unix 时间戳(秒) | ?ts={``{$timestamp()}} |
{``{$isoTimestamp()}} |
ISO 8601 格式时间戳 | ?t={``{$isoTimestamp()}} |
{``{$randomInt(min, max)}} |
指定范围随机整数 | ?count={``{$randomInt(1,100)}} |
2.4 脚本语法
用 {% ... %} 编写 JavaScript(基于 GraalJS / Nashorn 兼容子集)。
2.4.1 预请求脚本(请求发出前执行)
http
{%
const payload = { ts: Date.now() };
request.variables.set("body", JSON.stringify(payload));
%}
POST {{baseUrl}}/echo
Content-Type: application/json
{{body}}
2.4.2 响应处理脚本(请求完成后执行)
用 > 引出:
http
GET {{baseUrl}}/me
Authorization: Bearer {{token}}
> {%
client.test("返回 200", function () {
client.assert(response.status === 200, "HTTP 状态不是 200");
});
client.global.set("userId", response.body.json().id);
%}
2.4.3 内置对象与方法
| 对象 | 方法 | 说明 |
|---|---|---|
request.variables.set(key, val) |
设置请求级变量 | 仅当前请求可用 |
request.variables.get(key) |
读取请求级变量 | --- |
client.global.set(key, val) |
设置全局变量 | 跨请求、跨文件共享 |
client.global.get(key) |
读取全局变量 | --- |
client.test(name, fn) |
定义测试用例 | 在 Run 窗口展示结果 |
client.assert(cond, msg) |
断言 | 失败则标红 |
client.log(msg) |
输出日志 | 在 Run 窗口查看 |
response.status |
HTTP 状态码 | --- |
response.body.json() |
响应体解析为 JSON | --- |
response.body |
响应体原始字符串 | --- |
response.headers |
响应头对象 | --- |
2.5 认证语法
http
### Basic 认证
GET {{baseUrl}}/basic
Authorization: Basic user pass
### Bearer Token
GET {{baseUrl}}/me
Authorization: Bearer {{token}}
### OAuth2(手动填 token)
GET {{baseUrl}}/oauth
Authorization: Bearer {{accessToken}}
2.6 文件上传语法
http
### 单文件上传
POST {{baseUrl}}/upload
Content-Type: multipart/form-data; boundary=---Boundary
-----Boundary
Content-Disposition: form-data; name="file"; filename="test.png"
Content-Type: image/png
< ./images/test.png
-----Boundary--
2.7 外部脚本引用
http
GET {{baseUrl}}/users
Authorization: Bearer {{token}}
> scripts/assert-user.js
scripts/assert-user.js 内容:
javascript
client.test("Status 200", function () {
client.assert(response.status === 200);
});
client.test("Has data array", function () {
const json = response.body.json();
client.assert(Array.isArray(json.data), "data is not array");
});
2.8 其他实用语法
| 语法 | 作用 |
|---|---|
// @no-cookie-jar |
禁用 Cookie 持久化 |
// @name requestName |
给请求命名,方便引用 |
// @hidden |
隐藏敏感请求不在 Run 窗口展示 |
// @timeout 30000 |
设置超时(毫秒) |
! 前缀 |
标记请求为不保存响应 |
第三章 使用方式
3.1 快速开始(5 分钟上手)
Step 1:创建文件
项目根目录/
└── http/
├── auth.http
├── user.http
├── http-client.env.json
└── http-client.private.env.json
Step 2:写第一个请求
http
### 测试连通性
GET https://httpbin.org/get
Accept: application/json
点击左侧绿色箭头 → 响应在 Run 窗口展示。
Step 3:配置环境
json
// http-client.env.json
{
"dev": {
"baseUrl": "http://localhost:8080"
},
"prod": {
"baseUrl": "https://api.example.com"
}
}
右上角选择 dev 或 prod,{``{baseUrl}} 自动替换。
3.2 典型工作流:登录 → 业务请求
auth.http
http
### 登录并获取 Token
# @name login
POST {{baseUrl}}/auth/login
Content-Type: application/json
{
"username": "{{username}}",
"password": "{{password}}"
}
> {%
client.test("Login OK", function () {
client.assert(response.status === 200, "登录失败");
});
const token = response.body.json().accessToken;
client.global.set("token", token);
client.log("✅ Token 已保存到全局变量");
%}
user.http
http
### 获取当前用户信息
GET {{baseUrl}}/me
Authorization: Bearer {{token}}
> {%
client.test("200 OK", () => client.assert(response.status === 200));
client.global.set("userId", response.body.json().id);
%}
### 更新用户
PUT {{baseUrl}}/users/{{userId}}
Authorization: Bearer {{token}}
Content-Type: application/json
{
"nickname": "元宝"
}
执行顺序 :先跑 auth.http → login,再跑 user.http 中的请求。
3.3 统一登录的三种方案
IDEA 没有 Postman 的 "Collection 级 Pre-request Script",但可通过以下方式实现等效效果。
方案 A:手动先跑登录(推荐,最清晰)
规范:每次切环境 / 启动开发前,先执行 auth.http → login
优点:显式、可调试、可审查
方案 B:CLI 顺序执行(CI 场景推荐)
bash
# 先登录,再跑所有接口测试
ijhttp auth.http user.http order.http --env dev
方案 C:惰性刷新(判断 token 过期自动提示)
http
### 任意业务请求
GET {{baseUrl}}/me
Authorization: Bearer {{token}}
> {%
const exp = client.global.get("tokenExp");
if (!exp || Date.now() > exp) {
client.log("⚠️ Token 已过期,请重新执行 login 请求");
client.assert(false, "Token expired");
} else {
client.test("200 OK", () => client.assert(response.status === 200));
}
%}
登录时设置过期时间:
http
> {%
client.global.set("token", response.body.json().accessToken);
client.global.set("tokenExp", Date.now() + 55 * 60 * 1000); // 55 分钟
%}
3.4 CLI 使用(CI/CD 集成)
安装
ijhttp 随 IDEA 一起安装,路径通常在:
bash
# macOS
/Applications/IntelliJ\ IDEA.app/Contents/plugins/httpClient/bin/ijhttp
# Linux
~/idea/plugins/httpClient/bin/ijhttp
# Windows
C:\Program Files\JetBrains\IntelliJ IDEA\plugins\httpClient\bin\ijhttp.bat
常用命令
bash
# 指定环境运行
ijhttp --env-file http-client.env.json --env dev api.http
# 运行多个文件
ijhttp auth.http user.http --env dev
# 输出结果到文件
ijhttp api.http --env dev --output-dir ./results
# 静默模式(CI 中只输出失败)
ijhttp api.http --env dev --silent
GitHub Actions 示例
yaml
- name: Run API tests
run: |
$IJHTTP_PATH --env-file http-client.env.json --env ci api.http
env:
CI_TOKEN: ${{ secrets.API_TOKEN }}
3.5 从现有代码生成请求
| 来源 | 操作 |
|---|---|
| Spring Controller | 在 @GetMapping 等注解旁点灯泡 → Generate request in HTTP Client |
| OpenAPI / Swagger | 打开 openapi.json → 右上角 Generate HTTP Requests |
| Postman Collection | File → Import → Postman Collection,或用插件转换 |
| cURL 命令 | 复制 curl → Tools → HTTP Client → Convert cURL to HTTP Request |
3.6 响应查看与调试
- Run 窗口:展示状态码、耗时、响应头、响应体
- Services 工具窗 :
Alt+8打开,管理所有运行中的请求 - 响应保存到文件:
http
GET {{baseUrl}}/export
> ./responses/export.json
- 查看重定向链 :默认跟随重定向,可在脚本中读取
response.redirectedUrls
第四章 与 Postman 对比
4.1 功能对照总表
| 维度 | Postman | IDEA *.http |
|---|---|---|
| 请求编辑 | GUI 表单 | 纯文本 |
| 集合(Collection) | 树形结构 | 一个 .http 文件 ≈ 一个 Collection |
| 文件夹 | 支持多级 | ### 分段 + 多文件模拟 |
| 变量作用域 | Global / Env / Collection / Data / Local | Global / Env / File / Request |
| 动态变量 | {``{$guid}} {``{$timestamp}} |
{``{$uuid()}} {``{$timestamp()}} |
| Pre-request Script | ✅ 支持(请求级 + Collection 级) | ⚠️ 仅请求级 {% %} |
| Tests 脚本 | ✅ Tests Tab | ✅ > {% %} 响应脚本 |
| 断言语法 | pm.test / pm.expect |
client.test / client.assert |
| 全局前置脚本 | ✅ Collection Pre-request | ❌ 不支持,需显式登录请求 |
| 自动化工作流 | postman.setNextRequest |
❌ 顺序执行 |
| Data 驱动(CSV) | ✅ Collection Runner | ❌ 需手动模拟 |
| 环境变量管理 | GUI 环境下拉 | http-client.env.json + 右上角选择 |
| 私密环境变量 | 需手动不共享 | http-client.private.env.json(自动 gitignore) |
| Cookie 管理 | 自动 + 可视化管理 | http-client.cookies jar(可选禁用) |
| 认证方式 | 丰富的 Auth Tab | Header 手动写 / IDE 辅助 |
| 响应断言 | pm.expect |
client.assert |
| Mock Server | ✅ 内置 | ❌ 不支持 |
| Monitor / 定时任务 | ✅ Postman Cloud | ❌ 需外部 CI |
| 团队协作 | Postman Workspace(云端) | Git 版本控制(文本文件天然支持) |
| CI/CD 集成 | Newman CLI | ijhttp CLI |
| 测试报告 | Newman HTML 报告 | ❌ 无原生 HTML 报告 |
| gRPC 支持 | ✅ | ✅ |
| GraphQL 支持 | ✅ 强大 | ✅ 基础支持 |
| WebSocket 支持 | ✅ | ✅ |
| 代码生成 | 多种语言代码片段 | 从 Spring / OpenAPI 反向生成 |
| 版本控制 | 导出 JSON | .http 原生 Git 友好 |
| 学习曲线 | 低(GUI 引导) | 中(需记语法) |
| 适合场景 | 探索性调试、非开发团队协作 | 开发者日常、代码化接口管理、CI 集成 |
4.2 变量系统对比
| 作用域 | Postman | IDEA .http |
|---|---|---|
| 全局变量 | pm.globals.set/get |
client.global.set/get |
| 环境变量 | pm.environment.set + GUI 切换 |
http-client.env.json + 右上角切换 |
| 私密变量 | 环境里手动不共享 | http-client.private.env.json(自动覆盖) |
| 集合变量 | pm.collectionVariables |
无直接等价,用文件级 @var 代替 |
| 请求级变量 | pm.variables.set |
request.variables.set |
| Data 文件变量 | CSV / JSON 迭代 | 无原生支持 |
4.3 脚本迁移对照
Postman Pre-request → IDEA 预请求脚本
Postman:
javascript
// Pre-request Script
pm.globals.set("ts", Date.now());
pm.environment.set("nonce", CryptoJS.MD5(pm.globals.get("ts")).toString());
IDEA:
http
{%
request.variables.set("ts", String(Date.now()));
// IDEA 内置无 CryptoJS,可用 Java 类
var md5 = java.security.MessageDigest.getInstance("MD5");
md5.update(request.variables.get("ts").getBytes("UTF-8"));
var bytes = md5.digest();
var hex = Array.from(bytes).map(b => (b & 0xff).toString(16).padStart(2, "0")).join("");
request.variables.set("nonce", hex);
%}
GET {{baseUrl}}/sign?ts={{ts}}&nonce={{nonce}}
Postman Tests → IDEA 响应脚本
Postman:
javascript
// Tests
pm.test("Status 200", function () {
pm.expect(pm.response.code).to.equal(200);
});
const token = pm.response.json().token;
pm.globals.set("token", token);
pm.test("Has token", function () {
pm.expect(token).to.be.a("string");
});
IDEA:
http
> {%
client.test("Status 200", function () {
client.assert(response.status === 200, "not 200");
});
var token = response.body.json().token;
client.global.set("token", token);
client.test("Has token", function () {
client.assert(typeof token === "string" && token.length > 0, "no token");
});
%}
4.4 迁移路径建议
Step 1 导出 Postman Collection JSON
Step 2 用插件 / IDEA 内置导入 → 生成 .http 文件
Step 3 抽取 host/token 等进 http-client.env.json
Step 4 敏感信息移到 http-client.private.env.json
Step 5 pm.globals → client.global
Step 6 pm.test/pm.expect → client.test/client.assert
Step 7 登录接口独立为 auth.http,用 client.global 传 token
Step 8 CI 中用 ijhttp 替代 Newman
4.5 什么时候选哪个
| 场景 | 推荐 |
|---|---|
| 个人开发者、已在用 JetBrains IDE | ✅ IDEA .http |
| 团队有非开发人员(测试/产品) | ✅ Postman |
| 需要 Git 版本控制接口 | ✅ IDEA .http |
| 需要 Mock Server / Monitor | ✅ Postman |
| CI/CD 接口冒烟测试 | ✅ 两者皆可(Newman vs ijhttp) |
| 快速探索陌生 API | ✅ Postman(GUI 更直观) |
| 接口即代码、代码评审 | ✅ IDEA .http |
| 复杂数据驱动测试(CSV 迭代) | ✅ Postman + Newman |
附录
附录 A:完整项目目录结构推荐
project-root/
├── src/
│ └── main/
│ └── java/
│ └── com/example/
│ └── controller/
│ └── UserController.java
├── http/ # 接口请求文件
│ ├── auth.http # 登录、刷新 token
│ ├── user.http # 用户相关接口
│ ├── order.http # 订单相关接口
│ ├── product.http # 商品相关接口
│ ├── scripts/ # 公共脚本
│ │ ├── auth-check.js # token 校验
│ │ └── common-assert.js # 通用断言
│ ├── responses/ # 响应保存(gitignore)
│ │ └── .gitkeep
│ ├── http-client.env.json # 公共环境变量(提交 Git)
│ └── http-client.private.env.json # 私密变量(gitignore)
├── .gitignore # 忽略 private.env.json 和 responses/
└── README.md
附录 B:.gitignore 建议
gitignore
# IDEA HTTP Client
http/**/http-client.private.env.json
http/responses/
http/**/*.cookies
附录 C:常用脚本片段库
C.1 登录并保存 Token
http
### Auth: Login
# @name login
POST {{baseUrl}}/auth/login
Content-Type: application/json
{
"username": "{{username}}",
"password": "{{password}}"
}
> {%
client.test("Login OK", function () {
client.assert(response.status === 200, "登录失败: " + response.status);
});
var body = response.body.json();
client.global.set("token", body.accessToken);
client.global.set("refreshToken", body.refreshToken);
client.global.set("tokenExp", Date.now() + 55 * 60 * 1000);
client.log("✅ Token 已保存,过期时间: " + new Date(client.global.get("tokenExp")));
%}
C.2 刷新 Token
http
### Auth: Refresh Token
POST {{baseUrl}}/auth/refresh
Content-Type: application/json
{
"refreshToken": "{{refreshToken}}"
}
> {%
client.test("Refresh OK", function () {
client.assert(response.status === 200, "刷新失败");
});
client.global.set("token", response.body.json().accessToken);
client.global.set("tokenExp", Date.now() + 55 * 60 * 1000);
client.log("🔄 Token 已刷新");
%}
C.3 通用响应断言脚本
javascript
// scripts/common-assert.js
client.test("HTTP 200", function () {
client.assert(response.status === 200, "Expected 200, got " + response.status);
});
client.test("Content-Type is JSON", function () {
var ct = response.headers["content-type"] || response.headers["Content-Type"];
client.assert(ct && ct.includes("application/json"), "Not JSON: " + ct);
});
client.test("Response time < 2s", function () {
client.assert(response.time < 2000, "Too slow: " + response.time + "ms");
});
C.4 分页接口遍历
http
{%
request.variables.set("page", "1");
request.variables.set("pageSize", "20");
%}
### 获取分页数据
GET {{baseUrl}}/items?page={{page}}&size={{pageSize}}
Authorization: Bearer {{token}}
> {%
var json = response.body.json();
client.global.set("totalPages", json.totalPages);
client.global.set("currentPage", json.currentPage);
client.log("📄 Page " + json.currentPage + " / " + json.totalPages);
%}
C.5 文件下载并保存
http
### 下载文件
GET {{baseUrl}}/files/report.pdf
Authorization: Bearer {{token}}
> ./responses/report.pdf
附录 D:键盘快捷键速查
| 操作 | 快捷键(Windows/Linux) | 快捷键(macOS) |
|---|---|---|
| 创建 Scratch HTTP Request | Ctrl+Alt+Shift+Insert |
Cmd+Alt+Shift+Insert |
| 运行请求 | Ctrl+Enter |
Cmd+Enter |
| 运行所有请求 | Ctrl+Shift+F10 |
Cmd+Shift+R |
| 打开 Services 工具窗 | Alt+8 |
Cmd+8 |
| 跳转到变量定义 | Ctrl+B |
Cmd+B |
| 代码补全 | Ctrl+Space |
Cmd+Space |
| 格式化请求体 | Ctrl+Alt+L |
Cmd+Alt+L |
附录 E:常见问题排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
{``{var}} 未替换 |
变量未定义或环境未选 | 检查 env.json 是否选中对应环境 |
| 响应中文乱码 | 编码问题 | 在脚本中 response.body.toString("UTF-8") |
| Token 不生效 | 全局变量未设置成功 | 检查登录响应脚本是否执行、是否有报错 |
| 请求超时 | 默认超时 30s | 加 // @timeout 60000 |
| Cookie 干扰测试 | Cookie jar 持久化 | 加 // @no-cookie-jar |
脚本报错 ReferenceError |
JS 语法不兼容 | IDEA 使用 GraalJS,部分 Node API 不可用 |
| 环境变量找不到 | private env 覆盖了 public | 检查 private env 文件是否有同名 key |
| CLI 提示命令不存在 | ijhttp 不在 PATH |
使用完整路径或添加到 PATH |
附录 F:参考文档与资源
| 资源 | 链接 | 说明 |
|---|---|---|
| HTTP Client 语法参考 | https://www.jetbrains.com/help/idea/http-client-reference.html | 语法速查 |
| 环境变量与变量 | https://www.jetbrains.com/help/idea/http-client-variables.html | 变量系统详解 |
| CLI 工具 ijhttp | https://www.jetbrains.com/help/idea/http-client-cli.html | 命令行用法 |
| 从 Postman 导入 | https://blog.jetbrains.com/idea/2023/09/import-postman-collections-to-the-http-client/ | 迁移指南 |
| JetBrains Blog - HTTP Client | https://blog.jetbrains.com/idea/tag/http-client/ | 新功能公告与技巧 |
附录 G:版本变更要点
| IDEA 版本 | 重要变化 |
|---|---|
| 2017.3 | 首次引入 HTTP Client,支持基础请求 |
| 2018.2 | 支持环境变量、响应处理脚本 |
| 2019.2 | 支持 gRPC、WebSocket |
| 2020.3 | 引入 client.global、断言 API |
| 2021.2 | 支持外部 JS 文件引用 |
| 2022.3 | 支持 GraphQL、HTTP/2 |
| 2023.2 | 内置 Postman Collection 导入 |
| 2024.x | 脚本引擎切换为 GraalJS,性能提升 |
| 2025.x | 增强 CLI、改进 Services 工具窗 |