功能预览
附件下载时中文文件名乱码,多半是响应头里只写了 filename 或只写了 filename*。规范文档给出的做法是两个一起写:带星号的参数按 UTF-8 百分号编码且优先级更高,不带星号的保留 ASCII 形式兼容旧客户端。本文同时说明目录分隔符为什么要替换。
下载附件时中文文件名显示成乱码,原因通常不在文件本身,而在 Content-Disposition 这个响应头只写了其中一个文件名参数。规范文档的写法很清楚:filename 与 filename* 的差别在于后者采用 RFC 5987 第 3.2 节定义的编码,也就是 UTF-8 百分号编码;当同一个字段值里两个参数同时存在并且都能被理解时,带星号的那个优先;为了兼容性建议两个一起写。
带星号的参数解决的是「非 ASCII 字符怎么在头部里安全表达」,它把中文名按 UTF-8 编码后再百分号转义,浏览器解码即可还原;不带星号的参数承担的是兜底,写法上应把非 ASCII 字符替换成 ASCII 近似值,例如把带重音的字母换成普通字母,中文场景可以把原始文件名转成拼音或加日期前缀的英文形式。
只写不带星号的那个,中文在部分浏览器里会被原样透传成乱码;只写带星号的,遇到不认这个参数的旧客户端就会退化成默认名,用户拿到一串没有后缀的名字,反而更麻烦。
| 参数 | 编码方式 | 优先级 | 承担的角色 |
|---|---|---|---|
| filename | ASCII 近似值 | 较低 | 兼容旧客户端的兜底名 |
| filename* | UTF-8 百分号编码 | 两者都在时被采用 | 准确还原中文名 |
文档里有一条容易被踩的提醒:尽量避免在不带星号的 filename 里使用百分号转义序列,因为各浏览器处理不一致,有的会解码、有的不会。也就是说,同一个头部写法在两类浏览器里会得到两个不同的文件名,排查时很容易被误判成程序问题。
正确的分工是:需要转义的内容放在带星号的参数里,那里转义是有规范支持的;兜底参数只放纯 ASCII 的可读名字。
文件名里出现斜杠时,处理不当会变成目录穿越。稳妥的做法是在生成响应头之前就把原始名里的路径分隔符统一替换掉,同时把「.」和「..」这类片段单独处理,不要指望下游组件替你做净化。
这一步和上传侧的校验是两件事:上传时决定文件落在哪个目录、以什么后缀保存,下载时决定用户保存对话框里显示什么名字。两层各管一段,任何一层偷懒都会暴露。
以 AnQiCMS 这类内容管理系统为例,附件有两个入口:一是后台上传,二是通过 /api/import/archive 这类导入接口批量带正文资源。前者要注意响应头拼接的位置通常在下载处理逻辑里,编码要显式做,不要依赖框架默认值;后者批量导入时原始文件名来自压缩包或表格字段,更要在写入前完成分隔符替换与重名处理。
自 v3.6.5 起后台还支持把附件以 base64 编码内容通过接口上传,这条路径同样要保留原始名的处理规则:编码方式解决的是内容传输,文件名净化解决的是显示与落盘,两件事不能互相替代。
改完之后建议至少用三类客户端各下载一次同一个中文附件,确认保存对话框里的名字与后缀都正确,再看响应头里两个参数是否同时存在。
问:只写 filename* 能不能省事? 答:新客户端能正确显示,但不支持该参数的旧客户端会退回默认名,规范文档因此建议两个一起写以兼顾兼容性。
问:中文名可以直接写在不带星号的参数里吗? 答:不建议。头部字段按字面透传时非 ASCII 字符容易出问题,这正是带星号参数存在的原因,兜底参数应当只放 ASCII 近似名。
问:文件后缀要不要一起规范化? 答:要。后缀大小写混杂或缺失会同时影响下载显示与内容类型判断,建议在上传阶段就完成后缀白名单校验,下载阶段只做名字还原。
预览
接口文档面向调用方,说明怎么请求、有哪些公开能力;站点说明文件面向大语言模型,帮助模型理解和索引网站内容。两者读者不同、作用不同,一个管调用一个管理解,且都要能被抓取。站点说明文件由系统自动生成,配合站点地图分工:站点地图管发现,说明文件管理解。
预览
用一套系统管理多品牌、多主题网站时,站点边界决定域名与后台入口,语言层级决定翻译范围,内容模型决定字段是否共用。域名与主站语言按站点独立,模板与内容模型可在共享与独立之间取舍,导航与单页面按站点各自维护。
预览
人机验证从点选图片转向按风险放行,Cloudflare Turnstile 提供托管、非交互与不可见三种形态,勾选框只在风险偏高时才出现。令牌交到后端不等于安全,服务端仍要校验来源、按表单场景分级放行,并对验证失败给出可处理的返回。