新闻详情

新闻详情

首页 / 资讯中心 / 详情

Mac浏览器下载文件名乱码:从Content-Disposition到修复

发布时间:2026/10/1 5:00:45来源:尧图网络
Mac浏览器下载文件名乱码:从Content-Disposition到修复
1. 乱码不是玄学先把「乱」分成三类Mac 浏览器下载的文件名总是「乱码」这件事我被不同的人问过不下十次。最早我以为是个别网站的问题直到有次自己用 Safari 从公司内部系统下载一份带中文名的 PDF落盘之后变成了䏿–‡æµ‹è¯•.pdf才意识到这不是偶发——同一份文件在另一台机器上下来是好的在 Mac 上却翻车。后来又陆续遇到过%E4%B8%AD%E6%96%87.pdf、涓枃.pdf、还有干脆变成一串问号的版本。试过各种偏方之后我得出一个结论文件名乱码从来只有一个原因但表现形式至少有三种而大多数人一上来就用错了药结果越修越乱。这篇内容我打算把这件事从头到尾拆一遍先讲清楚乱码是怎么产生的再讲已经乱掉的文件怎么救回来然后是浏览器侧能做的取舍、服务端侧一行代码的修复最后是批量处理和长期预防。写完之后不管你是不懂编码的前端、天天跟素材打交道的设计师还是维护下载接口的后端都能找到直接能抄的那一段。1.1 三类长相三种病因判断病因最简单的办法是看乱码文件名的长相。这三种长相几乎不会混淆长相示例本质能不能救回来%E4%B8%AD%E6%96%87.pdf百分号编码没有被解码原样落盘能几乎 100% 还原䏿–‡.pdf、䏿–‡æµ‹è¯•.pdfUTF-8 字节被当成 ISO-8859-1 解码能前提是字符集没被替换过涓枃.pdf、锟斤拷.pdfGBK 字节被当成 UTF-8 解码产生了 UFFFD基本救不回来第一种其实是「假乱码」。浏览器拿到的字符串本身就是%E4%B8%AD%E6%96%87.pdf只是没人告诉它这是一段 URL 编码。这种通常是服务端或者前端脚本在做文件名时多绕了一层把已经编码的东西又当成了字面量。第二种是真正意义上的「编码错配」也是最常见的一种。中文的 UTF-8 字节序列是三个字节一组比如「中」是E4 B8 AD。如果这段字节被一个只认 ISO-8859-1 的解析器读走E4、B8、AD就会被当成三个独立的西欧字符于是「中」变成ä¸。「文」的E6 96 87对应æ–‡。这正好能解释为什么乱码里总是出现ä、æ、å、ç这些带分音符的字母——它们就是 UTF-8 首字节被拉丁字母表接住的产物。第三种最麻烦。GBK 的「中」是D6 D0被当成 UTF-8 解码时D6是个合法的双字节起始位但D0不构成合法续接解析器只能扔出一个替换字符 UFFFD也就是显示成「锟斤拷」或者「?」里的那一坨。信息在这一步就丢了任何脚本都救不回来只能重新下载。所以遇到第三种别浪费时间写脚本直接去找原始来源重下。1.2 为什么 Mac 上的表现和 Windows 不一样经常有人问同一个链接Windows 上下载下来文件名是好的Mac 上就乱。这不是 macOS 的锅也不是它比 Windows 差而是两边浏览器的「兜底策略」不同。服务端返回的文件名信息藏在 HTTP 响应头里字段叫Content-Disposition。这个字段的历史包袱特别重。早期规范RFC 2616 那一代规定filename参数只能是 ISO-8859-1 字符集中文字符根本不在允许范围内。后来 RFC 5987 补了一个新参数filename*允许用charsetlanguagevalue的格式承载 UTF-8比如Content-Disposition: attachment; filename*UTF-8%E4%B8%AD%E6%96%87.pdf问题是很多老系统只写了filename没写filename*。这时候浏览器就得自己猜服务端那串字节到底是什么编码。Chrome 和 Edge 的猜测逻辑经过多轮调整现在倾向于按 UTF-8 尝试Safari 在某些版本上更保守会先按 ISO-8859-1 解一遍发现不对再回头。移动端和桌面端还不一样。所以「同一个链接不同设备表现不同」本质是各家浏览器的猜测策略不同而不是有一方是错的。还有一层容易被忽略macOS 的文件系统本身对文件名有约束。APFS 用的是 Unicode但历史上有过 NFD 归一化的行为——HFS 会把文件名里的字符拆成「基字符 组合字符」。对中文来说影响很小因为绝大多数汉字在 NFC 和 NFD 下是同一个码点但如果你处理的是日文假名带浊音、韩文谚文或者越南语就会出现「看起来一样、实际比对不上」的诡异情况。另外 macOS 不允许文件名里出现半角冒号:Finder 会用/显示内核层面存的是:这个差异在跨系统传输时偶尔会咬人一口。2. 顺着 HTTP 头往上找文件名是在哪一步被改写的要真正解决问题得知道文件名从服务器到本地磁盘走了哪几步。整个链路大概是服务端生成Content-Disposition→ 中间层CDN、反向代理、网关可能改写 → 浏览器解析响应头 → 浏览器决定落盘名 → 操作系统写入文件系统。任何一步出错最后看到的就是乱码。我把最常见的几处翻车点按发生频率排一下。2.1 Content-Disposition 里 filename 与 filename* 的区别先看正确写法。如果你在写服务端代码生成中文文件名应该同时给出两个参数让老浏览器和新浏览器都能正确解析Content-Disposition: attachment; filenamefallback-name.pdf; filename*UTF-8%E4%B8%AD%E6%96%87.pdffilename里放 ASCII 兜底名比如拼音或者 IDfilename*里放百分号编码后的 UTF-8 真名。浏览器优先读filename*读不到再退回filename。这样即使遇到不认识filename*的老客户端也只会显示一个不漂亮但能用的英文名而不是一堆乱码。再看错误写法。最常见的两种第一种直接把中文字节塞进filename而不做编码Content-Disposition: attachment; filename中文测试.pdf严格来说这不符合规范。服务端框架输出时会把中文按它自己的编码通常是 UTF-8写成字节浏览器拿到这段字节后如果按 ISO-8859-1 解就变成第二种乱码䏿–‡æµ‹è¯•.pdf。第二种把百分号编码当成普通字符串填进filenameContent-Disposition: attachment; filename%E4%B8%AD%E6%96%87.pdf浏览器看到%只会当成普通字符落盘就变成%E4%B8%AD%E6%96%87.pdf。很多前端同学在 JS 里手动encodeURIComponent之后再拼 header就是踩了这个坑。filename*才需要百分号编码filename不需要。注意filename*的值里单引号必须有两个格式是UTF-8值中间那个语言标记可以留空但不能省略。写成UTF-8zh值也能用但兼容性不如留空。很多人只写一个引号导致整个参数被浏览器忽略。2.2 浏览器解码时的「猜编码」逻辑浏览器拿到filename之后到底怎么处理这块各家实现不太一样我实测下来大致是这样Chrome / Edge如果存在filename*直接按声明的字符集解码。如果没有把filename的字节按 ISO-8859-1 解码后再尝试转 UTF-8转失败就保留原样。Safari逻辑类似但在 URL 直接触发的下载里如果响应头缺文件名会用 URL 最后一段做文件名并且会尝试做一次 URL 解码。Firefox对filename*支持比较早也最规范遇到只有filename且检测到非 ASCII 字节时会做一轮启发式判断。这些「启发式」就是不确定性的来源。同一个响应头Chrome 可能猜对Safari 可能猜错。所以线上排查的时候别急着下结论说是浏览器 bug先把原始响应头抓出来看。用curl -I或者浏览器开发者工具的 Network 面板都能看到curl -sI https://example.com/download?id123 | grep -i content-disposition如果输出里只有filename而没有filename*而且值里出现了乱码字符那基本可以确定是服务端的问题客户端怎么调都没用。2.3 自建服务端最容易犯的三个错自己写下载接口的时候这三处最容易翻车我按踩坑频率从高到低列第一用框架默认的文件名输出不检查。很多框架的send_file或者FileResponse会帮你拼Content-Disposition但拼出来的格式取决于版本。老版本可能只填filename而且不做 ASCII 转义。升级框架或者手动指定比事后排查省事。第二中间件或者过滤器把 header 又加工了一遍。比如某个统一处理响应头的拦截器对所有 header 值做了 URL 编码或者做了ISO-8859-1转换你本地测没问题上线就乱。这类问题排查时要把链路每一段的输出都打出来对比。第三CDN 或者对象存储自动生成文件名。很多对象存储服务在返回文件时会用存储的 key 直接当filename如果 key 是中文又没做编码乱码就来了。这种情况要么改 key用 ID 或哈希要么在回源响应里覆盖 header。提示判断是源站问题还是中间层问题的快速办法是绕过 CDN 直连源站 IP 或内网地址测一次。两次结果一致说明是源站只有走 CDN 才乱说明是中间层。2.4 另一个隐形杀手Unicode 归一化前面提过macOS 的 HFS 会把文件名按 NFD 存储APFS 虽然底层不做强制转换但 Finder 和部分 API 仍会做归一化。这在中文场景下影响不大但有两种情况会出问题。一是日文、韩文文件名。比如带浊音符号的假名在 NFD 下会被拆成两个码点如果某个脚本按 NFC 比对文件名就会出现「明明文件在就是找不到」。二是从 macOS 打包发给别人的 zip解压到其他平台时文件名可能出现细微差异导致构建脚本按名字找文件时失败。处理办法是统一用 Python 的unicodedata做归一化import unicodedata name unicodedata.normalize(NFC, raw_name)习惯上我建议存储和比对都用 NFC因为绝大多数 Web 系统、Git、CDN key 都按 NFC 处理。如果在 Mac 上生成的文件要跨平台传输传输前做一次 NFC 归一化能省下不少事。3. 已经下载下来的乱码文件怎么救回来前面讲的是预防这一段讲急救。文件夹里已经躺着一堆䏿–‡.pdf的时候怎么把它们改回来。先说一个铁律动手之前先复制一份。改名操作是不可逆的脚本写错了一个字原始文件名就没了。我一般会先把整个文件夹复制一遍在副本上操作确认无误再覆盖。3.1 第一步永远是「先复制一份再动手」这条听起来像废话但我确实见过有人在几百个文件的目录里跑脚本正则写错一位把扩展名全改了结果所有文件都打不开。macOS 自带的「时间机器」虽然能恢复但那个流程走下来少说半小时不如复制文件夹花三秒钟。复制完之后先在副本里拿一个文件做实验。改对了再批量。改错了直接删副本重来。这个习惯能避免 90% 的翻车。3.2 判断原始字节序列的三种土办法动手改之前得知道病因。除了看长相还有几个更可靠的办法。第一个办法是看十六进制。用xxd或者hexdump看文件名的原始字节ls | head -1 | xxd | head -3不过这里要注意ls输出给你的已经是解码后的字符了看十六进制其实看的是终端编码后的结果用途有限。更直接的是看文件系统里的真实名字可以用 Python 的os.listdir配合os.fsencode拿到原始字节import os for name in os.listdir(.): print(repr(os.fsencode(name)))repr会把无法用当前编码表示的部分显示成\x转义这样一眼就能看出原始字节是什么。第二个办法是看来源。文件是从哪个网站下的那个网站的编码习惯是什么。国内老系统大量使用 GBK如果是这类来源第三类乱码的概率就高。第三个办法是反推。拿一段乱码字符串尝试encode(latin-1).decode(utf-8)如果能成功解出有意义的中文那就是第二类s 䏿–‡.pdf print(s.encode(latin-1).decode(utf-8))不管成不成都不会破坏原始文件所以可以放心试。3.3 手工改名小批量场景我常用的做法如果只有三五个文件直接手改最快。Finder 里选中文件按回车就能编辑名字中文可以直接输入改完回车确认。注意别改扩展名改错了系统可能认不出来。稍微多一点比如十几个可以用 Finder 的「批量重命名」功能选中一批文件右键选「给项目重新命名」然后在弹出的面板里选「替换文本」。这个功能适合把乱码前缀统一替换掉但不适合逐字还原因为它只做模式匹配。再往上数量或者乱码没有规律就得上脚本了。macOS 自带的mv配合 shell 循环也能做但编码处理这块 shell 比较弱容易在文件名含空格或特殊字符时出错。我的做法是直接用 Python理由后面说。3.4 批量还原一个 Python 脚本搞定Python 处理这个问题的优势在于它的encode/decode接口很明确能精确控制每一步的编码。下面这个脚本是我用了两年多的版本核心逻辑是「先试百分号解码再试 latin-1 还原」两个都失败就跳过#!/usr/bin/env python3 import os import sys from urllib.parse import unquote def restore(name): stem, ext os.path.splitext(name) # 路子一百分号编码 if % in stem: try: cand unquote(stem, encodingutf-8, errorsstrict) if cand ! stem and \ufffd not in cand: return cand ext except Exception: pass # 路子二UTF-8 字节被 latin-1 误读 try: raw stem.encode(latin-1) except UnicodeEncodeError: raw None if raw: for enc in (utf-8, gbk, big5): try: cand raw.decode(enc) if cand ! stem and \ufffd not in cand: return cand ext except UnicodeDecodeError: continue return None def main(): target sys.argv[1] if len(sys.argv) 1 else . dry_run --dry-run in sys.argv for name in sorted(os.listdir(target)): if name.startswith(.): continue new_name restore(name) if not new_name or new_name name: continue src os.path.join(target, name) dst os.path.join(target, new_name) if os.path.exists(dst): print(跳过目标已存在, new_name) continue print(f{name} - {new_name}) if not dry_run: os.rename(src, dst) if __name__ __main__: main()用法# 先干跑一遍看看到底会改成什么 python3 fixname.py ~/Downloads --dry-run # 确认没问题再真跑 python3 fixname.py ~/Downloads这里有几个我在实际使用中调出来的细节值得展开说一下。第一unquote一定要指定encodingutf-8。默认情况下unquote用的是utf-8但如果你不写读代码的人心里没底而且以后改起来容易忘。明确写出来是给自己留后路。第二encode(latin-1)会抛UnicodeEncodeError因为有些字符不在 latin-1 范围内。比如文件名里本身有正常的中文客户端已经正确解码了这时候encode(latin-1)就会失败。捕获异常并跳过的逻辑不能省否则脚本会中途崩溃。第三候选编码列表里我放了utf-8、gbk、big5三个。gbk覆盖简体中文的老系统big5覆盖繁体。顺序很重要utf-8放第一个是因为它最严格——一个字节序列如果凑巧能通过 utf-8 解码那么它的结构几乎一定是 utf-8误判率很低。第四\ufffd not in cand这个检查是为了拦住第三类乱码。如果解码结果里出现了替换字符说明原始字节已经丢失改出来的名字也不对不如不改。注意脚本只处理了一层目录不递归。这是故意的。递归脚本一旦判断失误改动范围不可控。需要处理多层目录时我建议逐层跑每层都先--dry-run确认。3.5 做成右键菜单Automator / 快捷指令实操脚本写好了每次开终端也麻烦。我把这个脚本包成了一个 Finder 右键菜单项选中文件直接点一下就改。做法是用 Automator 新建一个「快速操作」打开 Automator新建文稿类型选「快速操作」。顶部两个下拉框分别设为「工作流程收到当前」选「文件或文件夹」「位于」选「访达」。左侧搜索「运行 Shell 脚本」拖到右侧。「传递输入」设为「作为自变量」Shell 选/bin/zsh。脚本内容里调用你保存好的 Python 文件for f in $ do /usr/bin/python3 $HOME/bin/fixname_one.py $f done保存命名为「修复乱码文件名」。保存之后在 Finder 里选中乱码文件右键菜单的「快速操作」里就能看到它。第一次运行可能会弹权限提示允许之后就不会再问。如果不想写文件也可以用「快捷指令」App新建快捷指令添加「运行 Shell 脚本」动作接收「文件」类型的输入把上面的脚本粘进去保存后同样能出现在右键菜单里。macOS 13 之后快捷指令和 Finder 的集成做得比 Automator 顺我现在的机器上用的是快捷指令版本。4. 从源头减少乱码浏览器与下载链路的取舍客户端能做的其实有限但也不是完全没操作空间。这一段讲浏览器侧有哪些可以调的以及换工具时该怎么选。4.1 浏览器层面的几个可调项先说个坏消息Chrome 和 Edge 里没有「下载文件名编码」的开关。这个逻辑是写在内核里的不暴露给用户。网上流传的一些chrome://flags设置实测对文件名乱码无效别浪费时间。Safari 也一样没有相关偏好设置。所以如果服务端本身不修浏览器侧能做的只是「换一种拿文件的方式」。有几种变通做法值得一试。第一种是直接在地址栏访问文件 URL让响应头原样返回。有时候下载按钮走的是 JS 异步请求中间多了一层处理直接访问 URL 反而正常。第二种是用「链接另存为」这个操作在 Safari 和 Chrome 里都在右键菜单里走的是浏览器原生的下载链路可能和页面上那个按钮的链路不同。第三种是复制下载链接用curl拉curl -OJ https://example.com/download?id123-J让 curl 使用服务端返回的Content-Disposition文件名-O让它保存到本地。curl 对filename*的支持比较规范如果服务端写对了curl 下的名字通常是准的。这也能反过来验证服务端到底写没写对。4.2 对照实验同一链接换浏览器试排查阶段我强烈建议做对照实验。同一个链接在 Chrome、Safari、Firefox 里各下一遍把三个结果记下来浏览器结果文件名推断Chrome正常服务端大概率没问题Safari乱码可能是编码猜测策略差异全部乱码都是乱码服务端问题全部正常只有某个工具乱工具问题如果只有 Safari 乱其他正常那可以尝试让服务端补上filename*。有了显式声明各家浏览器的猜测就不需要了行为会统一。如果全部乱就别在客户端折腾了直接看服务器。这个实验我做过很多次结论很稳定80% 以上的乱码问题源头在服务端的 header 上。4.3 下载工具的适用场景有些场景下换个下载工具确实能绕开问题。比如专门的下载管理器通常对Content-Disposition解析得比较仔细也支持手动指定保存名。但这类工具引入了新的复杂度比如要处理连接数、断点续传、代理配置对于只是想把一个文件下对名字的需求来说属于杀鸡用牛刀。我的建议是日常下载用系统浏览器就够了遇到个别顽固的网站用curl -OJ手动拉一次比装一个下载器省事。真正高频遇到的乱码源还是应该推动服务端修否则你一个人绕过去了团队里其他人还在踩坑。5. 服务端修一行胜过客户端修一年如果你恰好是写下载接口的那个人那这部分是给你的。客户端改一百次不如服务端加一行。而且这行代码写起来真的不难。5.1 正确与错误写法对照我把常见的写法和问题整理成一张表对照着改就行写法结果评价filename中文.pdf部分浏览器乱码不推荐依赖浏览器猜测filename%E4%B8%AD%E6%96%87.pdf显示为百分号串错误filename不做 URL 编码filename*UTF-8%E4%B8%AD%E6%96%87.pdf现代浏览器正常推荐但要考虑老客户端filenamebackup.pdf; filename*UTF-8%E4%B8%AD%E6%96%87.pdf全部浏览器都正常最佳实践注意filename*的值要做百分号编码而且编码时用的是 UTF-8 字节。Python 里可以这样生成from urllib.parse import quote def content_disposition(filename, ascii_fallbackdownload.pdf): encoded quote(filename, safe) return fattachment; filename\{ascii_fallback}\; filename*UTF-8{encoded}quote的safe参数很重要它保证连/都被编码避免文件名里的斜杠被解析成路径分隔符。如果文件名里包含非 ASCII 字符ascii_fallback应该用拼音或者一个固定值不要直接把中文塞进去做兜底那样兜底本身就乱了。5.2 常见 Web 框架的处理差异不同框架对这件事的处理程度不一样我把几个常见的列一下都是我实际用过的Django 的FileResponse从 2.x 之后会自动处理filename*你把中文名传进去它帮你拼好。但要注意它的版本早期版本只填了filename且做了一次 latin-1 编码那个写法在新浏览器上会乱。升级到 3.x 以上基本不用管。Flask 的send_file在较新版本里也支持了但如果你用的是老版本或者手写响应头就得自己拼。手写的时候别用Response.headers[Content-Disposition] fattachment; filename{name}这种写法中文会出问题一定要走上面那个函数。Spring Boot 的ContentDisposition类提供了filename(name, StandardCharsets.UTF_8)的重载用它就行。别用只传字符串的那个重载那个默认按 ISO-8859-1 处理。Node.js 的res.download(path, filename)在新版本 Express 里会正确设置filename*老版本需要手动设 header。用content-disposition这个 npm 包比自己拼靠谱。.NET 的FileContentResult支持传文件名ASP.NET Core 会正确处理。老版本的Content-Disposition手写的话要注意用System.Net.Mime.ContentDisposition类而不是字符串拼接。提示不管用哪个框架改完之后一定要用curl -I验证一遍确认filename*真的出现在响应头里。有些框架的「自动处理」其实有开关默认关着。5.3 反向代理与对象存储层的坑源站改对了不代表用户拿到的是对的。中间层还有两个常见的改写点。第一个是反向代理。Nginx 如果用add_header手动加Content-Disposition配置文件里的中文在读取时按什么编码解释取决于环境输出到客户端时又不做百分号编码很容易变成第二类乱码。正确做法是不要在 Nginx 层拼中文文件名把这件事交给上游应用。第二个是对象存储。很多对象存储服务在直接返回文件时会用 key 作为文件名。如果 key 是中文服务端可能按 UTF-8 字节塞进filename也可能做一次编码行为不统一。稳妥的做法是把 key 设计成 ASCII比如用 ID 或者哈希真实文件名通过应用层的下载接口返回由接口来控制 header。我遇到过最隐蔽的一个情况源站写的是filename*但 CDN 在回源时把它丢了只保留了filename。最后排查了两个小时才发现是 CDN 配置里有一个「重写响应头」的规则。所以链路上每一段都要验证不要想当然。6. 常见问题速查与避坑经验最后这一段是我的实战笔记把高频问题和踩过的坑集中列出来方便对着查。6.1 速查表现象最可能的原因处理动作文件名是一串%E4%B8%ADheader 里填了编码后的值却没声明改用filename*文件名是䏿–‡这种带分音符的字母UTF-8 被按 ISO-8859-1 解读脚本还原或改服务端 header文件名是涓枃、锟斤拷GBK 字节被按 UTF-8 解信息已丢重新下载找源站修只有 Safari 乱Chrome 正常浏览器猜测策略差异补filename*文件名里出现而不是空格用了quote_plus或者前端处理不当换成quote或独立处理空格扩展名丢失文件名超长被截断缩短文件名中文最多约 85 字名字对了但打不开扩展名被改名脚本改错用os.path.splitext分离扩展名从 Mac 打包发出去后名字变了NFC / NFD 归一化差异打包前统一做 NFC6.2 几个我踩过的坑第一个坑是「用rename命令批量替换」。早期我用 shell 的rename配合通配符改文件名遇到文件名里有空格或者[这种字符时正则匹配会失控把一个文件改名两次。后来全改用 Python 的os.rename配合明确的目标名生成逻辑再没出过这种事。第二个坑是「在unquote里用了errorsreplace」。加这个参数看起来能让脚本不报错但代价是遇到非法序列时会静默生成替换字符改出来的名字看着像好的其实已经错了。我现在只在--dry-run模式里用宽容模式看看大概真跑的时候一定用errorsstrict出问题就跳过宁可少改也不要改错。第三个坑是「相信 Finder 显示的扩展名」。macOS 默认隐藏扩展名你看到的䏿–‡可能实际是䏿–‡.pdf。改名前一定要在 Finder 显示简介里确认真实文件名或者用ls -la看一眼。我见过有人把.pdf当成名字的一部分一起替换掉了结果文件变成无扩展名的二进制块。第四个坑是「把filename*的引号写成中文引号」。这个看起来可笑但真的会发生。从网页复制示例代码的时候被输入法替换成整个参数就废了。服务端语言通常不会报错只会静默输出一个浏览器认不出的 header表现就是文件名完全按 URL 走看起来也像乱码。排查的时候要把响应头原样 dump 出来看字符。6.3 长期防乱码的小习惯折腾多了之后我慢慢养成了几个习惯能省下后面大量的排查时间。第一个是下载目录定期清理。乱码文件堆着不处理下次想找的时候更找不到而且时间一长就忘了原始来源连重新下载的机会都没了。我的做法是每周扫一眼下载目录发现有乱码的当场改名或者删掉。第二个是给关键下载流程做一次验证。如果你维护的接口会被大量用户下载那值得在 CI 里加一条断言检查Content-Disposition里是否包含filename*。这个检查写起来很简单一次投入可以挡住后续所有的回归。第三个是团队里统一约定。文件名对外统一用 ID真实名字放在业务表里要展示真名的时候通过下载接口按规范设置 header。这样即使某天某个环节漏了编码也不会出现「存进 CDN 的就是乱码」这种不可逆的灾难。第四个是别迷信网上抄来的修复脚本。文件名编码这件事不同系统、不同浏览器、不同版本的行为都在变别人环境下能跑的脚本在你的目录里可能刚好把好文件也改了。永远先--dry-run确认每一个改动都符合预期再落盘。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Unity对象查找全解析:GetComponent、Find与性能优化实战 2026/10/1 5:57:35

Unity对象查找全解析:GetComponent、Find与性能优化实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
7900XTX 24G显存实战:Qwen 27B本地部署与量化推理指南 2026/10/1 5:57:35

7900XTX 24G显存实战:Qwen 27B本地部署与量化推理指南

1. 为什么选择 7900XTX 跑 Qwen 27B 这条路线1.1 一张消费级卡跑 27B 模型的现实账本手里有一张 7900XTX,24GB 显存,想跑 Qwen 27B 这个量级的模型,这件事在 2024 年之前基本属于“想想就好”,但到了现在,这条路已经能…

阅读更多 →
GitLab社区版内存占用优化:从bundle进程爆炸到宝塔环境平稳运行 2026/10/1 5:57:35

GitLab社区版内存占用优化:从bundle进程爆炸到宝塔环境平稳运行

我这台2核4G的服务器,之前跑宝塔LAMP一点问题没有,结果装上GitLab社区版之后,第二天早上起来发现面板都登录不进去了。SSH上去一看,好家伙,free -h显示内存用了3.6G,top里刷屏的全是bundle开头的Ruby进程。…

阅读更多 →
Java Agent项目中Redis与MySQL的状态协同设计 2026/10/1 5:57:35

Java Agent项目中Redis与MySQL的状态协同设计

1. 为什么《码上面试》Agent项目值得从第一天就拆开揉碎看?“《码上面试》Agent项目学习记录(一)”——这个标题乍看像一篇普通的学习笔记,但结合热搜词里反复出现的agent、Java、Redis、MySQL,再叠加“码上面试”这个…

阅读更多 →
加密压缩包与静默上传:313MB暗门攻击的检测与对抗 2026/10/1 5:57:35

加密压缩包与静默上传:313MB暗门攻击的检测与对抗

如果你在一个安全运营群里待得够久,一定见过类似的对话:有人发来一个压缩包,标注着“供应商资料,密码: 123”,大小313MB,文件名还算正常,但解压后里面躺着一个可执行文件。再往下查,…

阅读更多 →
大模型入门必读:从Transformer、Token到RAG,一文搞懂LLM核心概念 2026/10/1 5:57:28

大模型入门必读:从Transformer、Token到RAG,一文搞懂LLM核心概念

1. 用一个“读了很多书的实习生”类比,先搞懂大模型在做什么1.1 大模型不是“更聪明的搜索引擎”被问得最多的问题就是:“大模型是不是就是那种更聪明的搜索框?”我每次都会纠正——搜索引擎是帮你找信息,大模型是帮你生成信息。找…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉