API9 分钟阅读
REST API 中的 URL 编码最佳实践
掌握 REST API 开发中的 URL 编码技巧。学习如何正确编码查询参数和路径片段,构建可靠稳定的 API。
为什么 URL 编码对 API 如此重要
在 REST API 开发中,正确的 URL 编码至关重要。编码不当的 URL 会导致请求失败、安全漏洞、数据丢失,以及不同系统和编程语言之间的互操作性问题。作为 API 开发者,你既需要了解在发起请求时如何对 URL 进行编码,也需要了解在处理请求时如何对其进行解码。
编码路径参数
REST API 常常使用路径参数来标识资源。当这些参数包含特殊字符时,正确的编码就必不可少:
// 包含特殊字符的路径参数
// 资源:"Tom & Jerry's Show"
GET /api/shows/Tom%20%26%20Jerry%27s%20Show
// 使用 JavaScript
const showName = "Tom & Jerry's Show";
const url = `/api/shows/${encodeURIComponent(showName)}`;
// 值中包含正斜杠的路径
// 文件:"documents/my report.pdf"
GET /api/files/documents%2Fmy%20report.pdf
编码查询参数
查询参数是最常出现编码问题的地方。务必同时对键和值进行编码:
// 包含特殊字符的多个参数
GET /api/search?q=C%2B%2B%20programming&category=languages%20%26%20tools&page=1
// 使用 URLSearchParams(推荐)
const params = new URLSearchParams({
q: 'C++ programming',
category: 'languages & tools',
page: '1'
});
const url = '/api/search?' + params.toString();
处理查询字符串中的数组和对象
不同的 API 框架对数组参数的处理方式各不相同。以下是几种常见的约定:
// 重复键(最常见)
GET /api/items?tag=javascript&tag=typescript&tag=react
// 方括号表示法(PHP、Rails)
GET /api/items?tags[]=javascript&tags[]=typescript
// 逗号分隔(部分 REST API)
GET /api/items?tags=javascript,typescript,react
// 嵌套对象(方括号表示法)
GET /api/search?filter[status]=active&filter[sort]=date
Content-Type 与编码
Content-Type 请求头决定了请求体数据的编码方式:
application/x-www-form-urlencoded—— 与 URL 查询字符串类似。键和值都会被编码,空格会变成+multipart/form-data—— 用于文件上传。每个部分都有各自的编码application/json—— JSON 格式。请求体无需 URL 编码,但必须正确设置 Content-Type
API 安全注意事项
- 在服务端务必对解码后的 URL 参数进行校验和净化
- 警惕通过
%2e%2e%2f(../)等编码序列发起的路径遍历攻击 - 实施 URL 长度限制,以防范拒绝服务攻击
- 永远不要信任客户端的编码 —— 始终在服务端重新校验
- 提防双重编码攻击,即恶意输入在经过一轮解码后绕过过滤器
- 使用参数化查询,即便在 URL 解码之后也能防范 SQL 注入
测试 API 中的 URL 编码
在测试 API 端点时,请包含针对以下场景的测试用例:
- 含空格的参数(同时测试
%20和+) - 含保留字符(
&、=、?、#)的参数 - 含 Unicode 字符的参数
- 空参数值
- 极长的参数值
- 已编码的输入(双重编码检测)
- 含空字节(
%00)的参数