历史上的今天返回字段全解:list / title / year / content / img 一文读懂
# 历史上的今天返回字段全解:list / title / year / content / img 一文读懂
> 接口:历史上的今天(apiCode=119,接入点 119-42)· 免费 · 返回 JSON · 适用人群:开发者、前端工程师 · 阅读时间:约 6 分钟
## 核心要点
- 业务数据全部在 `showapi_res_body` 内;系统级字段(`showapi_res_code` 等)在外层。
- 每条事件 `year` 是**字符串**、`month`/`day` 是**数字**,混用类型要小心。
- `content` 与 `img` 仅在 `needContent=1` 时返回;`img` 无图时返回空字符串 `""` 而非 `null`。
## Why:先搞懂字段,少踩坑
接接口最怕"以为有这个字段、结果 undefined"。本文把返回结构一次性讲清,尤其点出 `year` 类型、`img` 空值、字段缺失条件这三处最容易出 bug 的地方。
## What:返回结构速览
| 层级 | 字段 | 类型 | 说明 |
|------|------|------|------|
| 系统级 | `showapi_res_code` | Number | 0 表示系统级成功(实测值 0) |
| 系统级 | `showapi_res_error` | String | 系统级错误信息,成功时为空 |
| 系统级 | `showapi_res_id` | String | 本次请求 ID |
| 系统级* | `showapi_fee_num` | Number | 实测响应中的调用计数(非文档示例显式字段) |
| 业务体 | `showapi_res_body` | Object | 业务数据容器 |
| 业务体 | `showapi_res_body.ret_code` | Number | `0` 成功 / `-1` 失败 |
| 业务体 | `showapi_res_body.list` | Array | 历史事件列表 |
| 列表项 | `year` | **String** | 年份,如 `"2008"`(注意是字符串) |
| 列表项 | `month` | Number | 月份,如 `2` |
| 列表项 | `day` | Number | 日,如 `20` |
| 列表项 | `title` | String | 事件标题,含年月日前缀 |
| 列表项 | `content` | String | 事件详情长文,**仅 `needContent=1` 返回** |
| 列表项 | `img` | String | 图片链接;无图时返回 `""`(空字符串) |
> 系统级错误判断用 `showapi_res_code`,业务层成功判断用 `showapi_res_body.ret_code`,两层不要混。
## How:安全解析字段
**Python**
```python
import requests
url = "https://route.showapi.com/119-42"
params = {"appKey": "YOUR_APPKEY"}
data = {"date": "0220", "needContent": "1"}
resp = requests.post(url, params=params, data=data, timeout=10)
result = resp.json()
if result.get("showapi_res_code") != 0:
raise SystemExit(result.get("showapi_res_error"))
body = result["showapi_res_body"]
if body.get("ret_code") != 0:
raise SystemExit(f"业务失败 ret_code={body.get('ret_code')}")
for item in body["list"]:
# year 是字符串,拼接口显示时直接 f-string 即可
label = f'{item["year"]}-{item["month"]:02d}-{item["day"]:02d}'
img = item.get("img") or "" # 无图时 img 为 "",用 or "" 兜底
content = item.get("content", "") # needContent=0 时无此键,用 get 兜底
print(label, item["title"], "有图" if img else "无图")
```
**cURL**
```bash
curl -X POST "https://route.showapi.com/119-42?appKey=YOUR_APPKEY" \
-H "content-type: application/x-www-form-urlencoded" \
-d "date=0220&needContent=1"
```
**Node.js(fetch)**
```javascript
const url = "https://route.showapi.com/119-42?appKey=YOUR_APPKEY";
const body = new URLSearchParams({ date: "0220", needContent: "1" });
const resp = await fetch(url, {
method: "POST",
headers: { "content-type": "application/x-www-form-urlencoded" },
body,
});
const result = await resp.json();
if (result.showapi_res_code !== 0) throw new Error(result.showapi_res_error);
const resBody = result.showapi_res_body;
if (resBody.ret_code !== 0) throw new Error(`业务失败 ret_code=${resBody.ret_code}`);
for (const item of resBody.list) {
const img = item.img || ""; // 空字符串兜底
const content = item.content || ""; // 可能不存在
console.log(`${item.year}-${String(item.month).padStart(2, "0")}-${String(item.day).padStart(2, "0")}`, item.title);
}
```
## 返回示例与解析
```json
{
"showapi_res_body": {
"list": [
{
"day": 20,
"title": "2008年2月20日 韩国一军用直升机坠毁造成7人死亡",
"year": "2008",
"month": 2,
"content": "2008年2月20日,韩国国防部确认……",
"img": "http://static1.showapi.com/app2/history_img/3cde348c8e484b5e8b7d708d145be1f3.jpg"
}
],
"ret_code": 0
}
}
```
解析要点:
- `year` 是 `"2008"`(字符串),做数值比较/排序时注意先转 `int`。
- `img` 有值时是 `http://static1.showapi.com/...jpg` 外链;无值时是 `""`。
## 进阶 / 边界
- **`year` 类型陷阱**:文档示例 `year:"1996"` 为字符串,若前端用 `item.year > 2000` 做数字比较会得到非预期结果,先 `Number(item.year)`。
- **字段缺失**:`needContent=0` 时 `list` 项里**没有** `content` 键,直接 `item.content` 会抛 KeyError/undefined,务必用 `get`/`||`。
- **`img` 空值**:判断有无图用 `img === ""`(或 `!img`),不要用 `img === null`。
## FAQ
**Q1:`year` 为什么是字符串而不是数字?**
官方文档示例即 `year:"1996"`(字符串)。以文档为准,解析时按字符串处理或显式转换。
**Q2:`content` 字段有时取不到?**
只有 `needContent=1` 才返回。列表展示场景不传即可,详情场景务必传 `1`。
**Q3:`img` 为 `null` 还是空字符串?**
实测为**空字符串 `""`**,不是 `null`,也不是缺字段。用 `img === ""` 判断是否无图。
**Q4:`ret_code` 和 `showapi_res_code` 有什么区别?**
前者是业务层(`showapi_res_body` 内,0/-1),后者是系统级(外层,鉴权/网关)。两层都要判。
## 相关能力 / 下一步阅读
- [历史上的今天:5 分钟接入,从注册到第一条历史事件](https://www.showapi.com/guides/history-today-quickstart-119) — 先跑通再回来对照字段。
- [历史上的今天:needContent 参数与图文详情的正确打开方式](https://www.showapi.com/guides/history-today-needcontent-119) — 搞懂 `content`/`img` 的返回开关。
- [历史上的今天:img 图片字段处理(空字符串、防盗链、懒加载)指南](https://www.showapi.com/guides/history-today-image-handle-119) — 图片字段的落地处理。
- **本系列共 10 篇**:查看[历史上的今天指南总目录](https://www.showapi.com/guides/history-today-guides-119)