HTTP 请求代码生成完全指南:fetch / axios / curl 最佳实践
从 GET 取数到 POST 创建再到 PUT/PATCH 更新,掌握 HTTP 方法语义、Content-Type 选择、Authorization 方案,写出安全高效的请求代码。
HTTP 请求看似简单,但选错方法或 header 会导致隐蔽的 bug。GET 用来取数,POST 创建,PUT 整体替换,PATCH 部分更新,DELETE 删除——每个都有特定含义,用错了服务器也许能工作但违反了 REST 约定。本指南从方法语义讲起,逐一覆盖 Content-Type、Authorization、错误处理、超时与重试,并用本站工具生成可用的 fetch / axios / curl 代码。
HTTP 方法的正确语义
| 方法 | 幂等 | 有 body | 用途 |
|---|---|---|---|
| GET | ✓ | ✗ | 读取资源,不修改服务器 |
| POST | ✗ | ✓ | 创建新资源,或触发服务端动作 |
| PUT | ✓ | ✓ | 整体替换资源(全量更新) |
| PATCH | ✗ | ✓ | 部分修改资源 |
| DELETE | ✓ | ✗ | 删除资源 |
| HEAD | ✓ | ✗ | 同 GET 但不返回 body,常用于检查资源是否存在 |
幂等:重复执行多次与执行一次结果相同。GET/PUT/DELETE 幂等,POST/PATCH 不幂等。
常见错误: - 用 GET 修改数据(导致被浏览器缓存,修改失效) - 用 POST 代替 PUT(语义不清,难以预测行为) - 用 DELETE 而不返回成功状态(删除的资源去哪了?)
Content-Type 与请求体格式
最常见的三种:
application/json(推荐): ``` Content-Type: application/json
{"name":"Alice","age":30} ``` 现代 API 的标准。跨语言通用,嵌套灵活。缺点:不支持文件上传。
application/x-www-form-urlencoded: ``` Content-Type: application/x-www-form-urlencoded
name=Alice&age=30
``
老式 HTML 表单使用。URL 中含 & 会变 %26`,不适合复杂数据。但很多老网站仍用。
multipart/form-data: ``` Content-Type: multipart/form-data; boundary=----Boundary123
------Boundary123 Content-Disposition: form-data; name="name"
Alice ------Boundary123 Content-Disposition: form-data; name="file"; filename="photo.jpg" Content-Type: image/jpeg
[二进制内容] ``` 唯一支持文件上传的格式。浏览器上传表单自动用这个。
选择规则: - REST API(推荐) → JSON - HTML 表单 → form-urlencoded 或 multipart - 文件上传 → 必须 multipart
Authorization 认证方案
服务器如何确认你是谁?四种常见方案:
1. Bearer Token(最常用):
``
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
``
通常是 JWT。适合 API 认证和移动 app。
2. Basic Auth:
``
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
`
Base64 编码的 username:password`。简单但不安全,必须用 HTTPS,很多接口仍用(如 npm registry、GitHub personal access token)。
3. API Key:
``
X-API-Key: sk-1234567890abcdef
`
或放 query 参数 ?api_key=...`。不安全,但简单。常见于公开 API(天气、地图、翻译)。
4. OAuth2:
``
Authorization: Bearer access_token_here
``
结合 refresh token 的完整授权框架。微信、QQ、Google 登录都用 OAuth2。
选择规则: - 内部 API → Bearer Token(JWT) - 第三方服务接入 → OAuth2 - 小型公开 API → API Key - 遗留系统 → Basic Auth(但要用 HTTPS)
Fetch vs Axios vs curl 对比
Fetch API(原生,无依赖):
``
const res = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Alice' })
});
const data = await res.json();
``
优点:原生 API,无需引入库,Promise 原生支持。缺点:没有内置超时、重试、请求拦截器,手工处理比较繁。
Axios(最流行的 HTTP 库):
``
const res = await axios.post('/api/users', { name: 'Alice' }, {
timeout: 5000,
headers: { 'Content-Type': 'application/json' }
});
const data = res.data;
``
优点:超时、重试、拦截器都有,API 简洁。缺点:需要依赖。
curl(命令行):
``
curl -X POST https://api.example.com/api/users \\
-H "Content-Type: application/json" \\
-d '{"name":"Alice"}'
``
优点:快速测试,无环境要求。缺点:不适合复杂逻辑。
本站工具自动生成这三种代码,选择对应场景即可。
错误处理与状态码检查
Fetch 的坑:fetch 只在网络错误时 reject,4xx/5xx 不会。
try {
const res = await fetch('/api/users');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (err) {
console.error('Request failed:', err);
}
```
**必须手工检查 res.ok 或 res.status**。
Axios 的便利:状态码 4xx/5xx 自动 reject。
try {
const res = await axios.get('/api/users');
return res.data;
} catch (err) {
if (err.response) {
console.error(`Server error ${err.response.status}`);
} else if (err.request) {
console.error('No response');
}
}
常见状态码: - 200 OK / 201 Created / 204 No Content - 400 Bad Request / 401 Unauthorized / 403 Forbidden / 404 Not Found - 500 Internal Server Error / 503 Service Unavailable
不同的错误需要不同处理(401 要重新登录,503 可重试)。
超时与重试策略
设置超时(防止无限等待):
Fetch(无内置):
``
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), 5000);
try {
return await fetch(url, { signal: controller.signal });
} finally {
clearTimeout(id);
}
``
Axios(简单):
``
await axios.get(url, { timeout: 5000 });
``
重试策略:
``
async function retryFetch(url, maxRetries = 3, delay = 1000) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fetch(url);
} catch (err) {
if (i === maxRetries - 1) throw err;
await new Promise(r => setTimeout(r, delay * Math.pow(2, i)));
}
}
}
``
重试原则: - GET / HEAD / DELETE / PUT:幂等,可安全重试 - POST / PATCH:非幂等,重试需谨慎(可能重复创建) - 只重试 5xx / 408 / 429,不重试 4xx(客户端错误重试无效) - 指数退避延迟(1s → 2s → 4s),避免击垮服务器
CORS 跨域与浏览器限制
浏览器同源策略:JavaScript 只能请求同域名/同端口的资源。跨域请求会被浏览器拦截。
CORS 预检请求(OPTIONS):浏览器自动发送,服务器响应允许的方法和 header。
Fetch 时浏览器自动发 OPTIONS,如果服务器没有 CORS header,请求被拦截。
- 服务器加 CORS header:
- 用 Proxy(开发时):Next.js / Create React App 的 setupProxy
- 用 JSONP 或 iframe(已过时)
注意:curl 和 Node.js 后端无 CORS 限制,只有浏览器中的 JavaScript 受限。本站工具生成的前端代码,如果跨域需确保目标 API 开启 CORS。
常见问题
什么时候用 PUT,什么时候用 PATCH?
PUT 替换整个资源(全量),PATCH 修改部分字段。例:更新用户,PUT 时必须发全部字段,PATCH 只发改变的字段。但多数小型 API 都用 PATCH。
Fetch 默认是 GET 吗?
是。不指定 method 时默认 GET;如果提供 body,默认变 POST(但需明确指定 method)。
如何在浏览器中传文件?
用 FormData + multipart/form-data。Axios 自动识别 FormData 并设置正确的 Content-Type。
能在 Authorization 里放 API Key 吗?
可以,但规范做法是用自定义 header(如 X-API-Key)或放 query 参数。Bearer token 严格指 OAuth2 / JWT。
302 重定向我的代码需要处理吗?
Fetch / Axios 默认自动跟随重定向(最多 5 次)。通常不需要手动处理,除非特别不想跟随。