min/max 必须严格为 YYYY-MM 格式(如“2026-08”),缺位补零、年月完整、分隔符为短横线,否则浏览器静默忽略;动态生成需用 padStart(2, "0"),服务端必须二次校验格式与范围。

min/max 必须是 YYYY-MM 格式,否则直接失效
浏览器对 min 和 max 的值极其挑剔:写成 min="2026-8"(月份没补零)、min="08"(缺年份)、min="2026/08" 都会被忽略,控件既不报错也不限制。只有形如 min="2026-08" 这种严格两位补零的完整格式才生效。
常见错误场景:
- 后端返回的月份是数字
8或字符串"8",前端直接拼进min→ 失效 - 用
new Date().toISOString().slice(0, 7)动态生成,但在 UTC+8 时区下可能得到上月(比如本地 8 月 1 日凌晨,UTC 是 7 月 31 日)→ 范围错位 - 用户手动编辑输入框,删掉年份只留
-08,控件变空但表单仍可提交 → 后端收到空字符串
安全做法:
- JS 动态设置时用:
year + "-" + String(month).padStart(2, "0"),其中month是 0–11 的整数 - 想限制“2026 年全年”,必须同时设
min="2026-01"和max="2026-12",单设一个没用 - 服务端不能信任前端传来的
min/max值,需二次校验提交的value是否在业务允许范围内
value 不合法会导致控件清空,且 checkValidity() 返回 false
input[type="month"] 的 value 是只读字符串,任何非标准格式都会让它回退为空状态——哪怕只是少个零、换了个分隔符。
立即学习“前端免费学习笔记(深入)”;
典型翻车点:
- 后端返回
"2026/08"或"2026年08月",直接赋给input.value→ 输入框变空 - JS 拼字符串时写成
`${y}-${m}`,而m是8→ 得到"2026-8"→ 失效 - 用户粘贴
2026-13(非法月份)→ 控件清空,但input.value变成空字符串,不是"2026-13"
处理建议:
使用 Puppeteer + Chrome 将 HTML 渲染为中文 PDF,自动处理图表等待、Tab 展开、动画、测高、白边消除、防分页,适用于看板、报表、网页和交互图表转 PDF。
- 赋值前先正则清洗并校验长度:
val.replace(/\D/g, "-").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-"),再判断是否匹配^\d{4}-\d{2}$ - 始终用
input.checkValidity()判断用户是否真的选了有效值,别只看input.value !== "" - 提交前用
FormData.get("field")拿到的仍是字符串,不会自动转换,别误以为是 Date 对象
浏览器支持和 fallback 行为差异大,别默认启用
原生 type="month" 在 Safari 15.4 之前完全不支持,iOS 16.4 / macOS 13.3 才稳定;安卓部分 WebView 直接 fallback 成无校验的文本框,且用户能输任意字符。
这意味着:
- 不能只靠
min/max做业务约束,它们在旧版 Safari 或 WebView 中静默失效 - 样式无法定制:伪元素如
::-webkit-inner-spin-button对它无效,也无法隐藏年份或禁用滚动 - 若需“只选 Q3”“禁用已过月份”“显示中文月份名”,原生控件做不到,必须换 JS 方案(如 flatpickr 配置
mode: "month")
最小兼容策略:
- 用
document.createElement("input").type === "month"检测支持度 - 不支持时降级为两个
select(年份 + 月份)或带格式提示的input type="text",并加 JS 校验 - 所有日期逻辑(如范围联动、季度限制)必须由 JS 实现,不能依赖原生行为
后端拿到的是字符串,不是 Date,SQL 查询要转范围
表单提交或 FormData 获取到的永远是 "2026-08" 这样的字符串,不是 Date 对象,也不是时间戳。直接拿它去查数据库会出错。
正确处理方式:
- Java Spring Boot:加
@DateTimeFormat(pattern = "yyyy-MM")注解,否则抛DateTimeParseException - PHP:用
DateTime::createFromFormat("Y-m", $_POST['month'])构造,再取$date->format("Y-m-01")和$date->format("Y-m-t")得当月起止 - SQL 查询别写
WHERE MONTH(created_at) = '2026-08'(类型错配),应写:WHERE created_at BETWEEN '2026-08-01' AND '2026-08-31'
最易被忽略的一点:前端看似选了“2026-08”,但用户可能没选、选了空、或手动删成非法格式——后端永远要按字符串判空、格式校验、范围检查,不能假设它一定合法。


















