用户撞上404的那一刻,请求已经不在你的应用里了,本地化也就管不到

用户撞上404的那一刻,请求已经不在你的应用里了,本地化也就管不到
张文保 更新 36 分钟阅读 1,938 阅读
本文目录
  1. 站上每一个字都能本地化,为什么偏偏出错那一页不能?
  2. 一家宠物用品站的越南语页面,三个月没人发现的那一页
  3. 出错这一刻的特殊之处:请求已经不在你的应用里了
  4. 所以这不是没做,是没有地方可做
  5. 先把故障页按归属分成三类
  6. 错误页到底是谁输出的,三层来源里哪一层没有语言这个概念?
  7. 应用层:它知道用户是谁,也知道该说哪门语言
  8. 服务器层:它只认文件路径,不认用户
  9. 边缘层:这时候你的代码一行都没执行
  10. 用一次抓包分清自己站上的三层各占多少
  11. 服务器软件自带的那份多语言错误页,到底覆盖了哪些语言?
  12. 它其实早就准备好了,只是没人打开过
  13. 那份清单上有21门语言,默认优先级表里只挂了14门
  14. 清单上没有的那些语言,恰好是你要开的市场
  15. 打开它要付什么代价
  16. 语言协商能不能救场,浏览器发过来的那个头够用吗?
  17. 请求头里确实带着语言偏好
  18. 浏览器偏好和市场版本是两个坐标系
  19. 匹配规则比想象中松,会挑出你没准备的那一门
  20. 什么时候该信这个头,什么时候该信地址
  21. 一版英文错误页到底够不够用,判据是什么?
  22. 够用这个结论是在什么前提下成立的
  23. 三个把它推翻的场景
  24. 按流量算这一页的价值,算法跟别的页不一样
  25. 三档投入分别做到哪一档
  26. 错误页的文案在小语种里,为什么比英语更难写?
  27. 它是全站语气要求最高的一页
  28. 道歉这件事在各语言里的分寸不一样
  29. 文本膨胀在这一页格外要命
  30. 别在错误页上玩梗,尤其是在不是你母语的市场
  31. 本地化错误页的时候,怎么保证状态码不被改坏?
  32. 状态码和文案是两件事,改文案不该动状态码
  33. 最常见的一种改坏:指到外部地址就变成了跳转
  34. 软404在多语言站上会多出一种成因
  35. 上线后怎么验状态码真的对
  36. 那些你根本改不到的错误页,该怎么处理?
  37. 边缘节点的拦截页
  38. 支付网关跳回来的那一页
  39. 第三方组件自己弹的提示
  40. 改不到的时候,能做的三件事
  41. 那家宠物用品站后来做了什么,波兰语那边为什么一直没事
  42. 同一套配置,两个市场结果不一样
  43. 定位它花了很久,因为报表里没有这一类
  44. 改了三处
  45. 结果里最有意思的是那个减法
  46. 把错误页的语言收成一张能照着做的清单
  47. 半天能做完的第一版
  48. 一周能做完的完整版
  49. 上线前的六项检查
  50. 三条该让你停下来的反信号
  51. 常见问题解答
  52. 多语言站的404页面,到底要不要按语言做几份?
  53. 服务器自带的多语言错误文档,直接用行不行?
  54. 能不能直接读浏览器发来的语言偏好来决定错误页语言?
  55. 把错误页指到另一个语言目录,会不会影响状态码?
  56. 语言回落导致的软404,怎么跟普通软404分开?
  57. 边缘节点和防火墙挡下的页面改不了,还能做什么?
  58. 错误页上的文案可以用机器翻译吗?
  59. 权威参考资料

摘要:站上每一个字都能本地化,唯独出错那一页经常不能。原因不在预算也不在流程:撞上404或者503的那一刻,请求多半已经离开了你的应用,输出这一页的是服务器软件或者边缘节点,而那一层压根不知道用户是谁。服务器自带的多语言错误文档其实有21门语言,默认优先级表里只挂了14门,而阿拉伯语、越南语、泰语、印地语一门都没有。本文拆开三层来源、语言协商靠不靠得住、一版英文页够不够用的判据,以及怎么在不改坏状态码的前提下把这一页做出来。

站上每一个字都能本地化,为什么偏偏出错那一页不能?

一家宠物用品站的越南语页面,三个月没人发现的那一页

有个客户做宠物用品,猫砂盆、牵引绳、宠物笼、猫爬架这几条线。

越南语和波兰语两个市场,页面翻译请的都是本地写手,验收流程也一样。

那年秋天他们做了一次品类重构,一批旧地址失效,重定向做得不算干净。

三个月后越南站的品牌词表现莫名其妙地滑了一截,波兰站没事。

保哥拿越南本地的网络环境挨个点了一遍旧地址,点到第四个的时候看见了那一页:一张纯英文的服务器默认错误页,没有导航,没有搜索框,落款是服务器软件的版本号。

更尴尬的是那页上唯一一行大字写着请求的资源在此服务器上未找到,而这句话是二十多年前写进软件里的默认文案,跟这家店、这个品牌、这门语言都没有半点关系。

那一页还有个额外的坏处:落款把服务器软件和版本号一并写了出来。这在安全上是不必要的暴露,把这一页做掉顺手就能把这行去掉,属于一次改动两处收益。

出错这一刻的特殊之处:请求已经不在你的应用里了

这件事值得单独拆,因为它跟别的本地化缺口不是一个成因。

页面上的文案没翻译,多半是没抽出来或者没排上期,属于流程问题。

错误页不一样,它经常是根本没有地方可以做。

用户能看到本地化内容的前提是请求走到了你的应用里,应用知道他是谁、来自哪个市场、该用哪套语言资源。

而404和503恰好是那一类请求走不到应用里的情形:地址不存在,应用没被调用;服务过载,应用起不来。这时候站出来说话的是它前面那一层,那一层手里没有语言这个概念。

还有第三种情形也归这一类:跳转链断在中间。用户从外部链接进来,中间某一跳指向了一个不存在的位置,最终停在的那一页同样由服务器输出,而不是你的应用。

所以这不是没做,是没有地方可做

这个区别很重要,因为它决定了往哪儿使劲。

如果是没做,解法是排期、找译者、走验收。

如果是没有地方可做,解法在配置层,跟译者一点关系都没有。

很多团队在这一页上反复讨论文案该怎么写、要不要幽默一点,然后发现写好的文案根本没地方放。

顺序应该反过来:先确认这一页由谁输出,再决定它能承载多少语言。本站在界面文案那批从没进过翻译文件的字里讲过一次相近的错觉,那边是字没被抽出来,这边是字压根不在你的程序里。

分辨自己属于哪一种有个很快的办法:把那一页的源码存下来,搜一下有没有你自己的模板痕迹,比如导航结构、样式表地址、统计代码。有就是应用输出的,没有就不是。三十秒能判完。

先把故障页按归属分成三类

动手之前把站上的故障页分成三类,后面所有决策都按这三类走。

第一类是应用输出的,比如商品下架页、搜索无结果页、登录失效提示。

第二类是服务器软件输出的,比如地址不存在、维护中、权限不足。

第三类是边缘节点或者第三方输出的,比如内容分发网络的拦截页、防火墙的挡板、支付网关跳回来的失败页。

第一类跟别的页面没区别,本来就该本地化;第二类要动配置;第三类多数动不了,只能绕。分类这一步花不了二十分钟,却能省掉后面所有的方向性争论。

还有一类边界情形值得单列:托管在静态平台上的站。这类站没有传统意义上的服务器配置,故障页由平台的路由规则决定,能力介于第二类和第三类之间,要看平台文档里的重写规则支持到什么程度。

错误页到底是谁输出的,三层来源里哪一层没有语言这个概念?

应用层:它知道用户是谁,也知道该说哪门语言

应用层输出的故障页其实是最幸运的一类。

请求已经进来,会话在,语言资源加载好了,路由也知道当前是哪个市场。

这一层的故障页跟普通页面走同一套模板和同一份翻译文件。

它出问题的方式也跟普通页面一样:某几句提示没被抽出来,或者抽出来了但目标语言里缺译。

换句话说,应用层的故障页不属于本文要解的问题,它属于界面文案那一类,按老办法处理就行。

应用层的故障页还有一个特有的坑:它很容易返回200。因为它是被正常路由渲染出来的一个页面,框架不会自动把状态码改成404,需要显式设置。这就是软404最常见的来源。

服务器层:它只认文件路径,不认用户

再往外一层是服务器软件,这一层是本文的主角。

它的配置里有一条指令,作用是把某个状态码映射到某个文件。

这条指令的参数是一个路径,不是一个函数。

路径是死的,同一个状态码永远指向同一个文件,除非你额外做点什么。

所以默认情况下,一个站只有一份404页,不管来访的是德国人、越南人还是爬虫。语言在这一层不是被忽略了,是这一层的数据模型里没有这个维度。

这一层还有一个容易被忽略的能力:部分服务器软件允许在指向内部页面的同时显式改写返回的状态码。这个能力用对了很有用,用错了就是把404变成200,正好制造出一批软404。

边缘层:这时候你的代码一行都没执行

最外面那一层最麻烦。

内容分发网络在边缘节点上就把请求挡了,源站什么都不知道。

网络应用防火墙判定这次访问可疑,直接返回一张挡板页。

这两种情况下你的服务器配置完全没参与,服务器软件那条指令也就无从谈起。

能改的只有边缘服务商自己的自定义错误响应功能,而它的能力边界由服务商决定,多数只允许你上传一份静态页面。

边缘输出的挡板页还有一个额外风险:它可能被抓取程序拿到并当成你的内容。挡板页多半是英文的、内容雷同的、没有导航的,一批这样的页面被抓走,对站点的整体判断没有任何好处。

用一次抓包分清自己站上的三层各占多少

纸上谈兵没用,得知道自己站上这三层的实际分布。

做法是把最近三个月产生过404和503的地址导出来,取前一百条。

逐条请求一次,只看响应头里的服务器标识和几个特征字段。

带着应用框架特征的是第一类,只有服务器软件标识的是第二类,带着边缘服务商标识的是第三类。

一百条跑完通常半小时,结果往往出人意料:多数团队以为绝大部分故障页由应用输出,实测下来第二类和第三类加起来能占到一半以上。服务器配置那份清单里讲过怎么读这些响应头,配着看能省不少事。

记录建议固定成五列:地址、状态码、响应头里的服务器标识、判定归属、页面语言。第五列要靠人眼看一下页面正文是什么语言,这一列正是所有报表都不会给你的那个信息。

服务器软件自带的那份多语言错误页,到底覆盖了哪些语言?

它其实早就准备好了,只是没人打开过

这里有个不少人不知道的事实。

主流的开源服务器软件在安装时就附带了一整套翻译过的错误文档。

官方文档里专门有一节讲这件事,标题就叫多语言自定义错误文档。

它还附了一份现成的配置文件,放在额外配置目录里,取消注释就能生效。

也就是说,多数站上其实躺着一套现成的本地化错误页,只是从来没有人把它接上过。这大概是本站写过的所有本地化缺口里,修复成本最低的一个。

要提醒一句的是这套现成资产只存在于其中一类服务器软件上。另一类常见的服务器软件没有等价的自带多语言错误文档,它的错误页指令只能指向一个固定文件,多语言要靠自己写规则实现。

顺带说一句,这套资产的存在本身也说明了一件事:二十多年前设计这套软件的人是认真考虑过多语言的,他们把这条路铺好了,只是后来没有人走。技术上的可能性和组织上的执行之间,隔着的从来不是难度。

那份清单上有21门语言,默认优先级表里只挂了14门

把那批文件打开数一遍,会看到一个有意思的差额。

每个状态码对应一个多变体文件,文件里按语言列出了变体,数下来是21门。

而官方给的那份配置文件里,语言优先级指令上只列了14门。

差出来的7门里包括俄语、塞尔维亚语、葡萄牙本土葡语、挪威语、爱尔兰语和两种中文。

这些翻译文件躺在磁盘上,只有当浏览器明确要求它们的时候才会被挑到;在偏好不明确的场合,服务器会按优先级表回落到英语。你付了硬盘空间,却没有用上那份翻译。

这个差额多半是历史造成的:翻译文件是社区陆续贡献进来的,而那份示例配置写好之后没有跟着更新。这类差额在开源项目里很常见,也正因为常见,没有人会主动去数一遍。

对做站的人来说,结论是别相信示例配置里的清单,要自己打开那批文件数一遍实际有哪些语言。数一遍不到五分钟,而它决定了你要不要为某门语言另外准备文件。

清单上没有的那些语言,恰好是你要开的市场

更值得看的是完全不在这21门里的那些。

阿拉伯语没有,希伯来语没有,越南语没有,泰语没有,印地语没有。

希腊语、匈牙利语、芬兰语、乌克兰语、印尼语、波斯语,一门都没有。

这份清单的构成大致对应二十多年前的互联网版图,而它此后基本没有变过。

这跟本站反复遇到的那条规律又一次对上了:一整套默认值是照着某个时期的典型场景定下来的,场景早就变了,默认值还留在原地。开东南亚和中东市场的人,在这一页上是彻底没有存量可用的。

自己补一份的成本其实不高。那批文件是多变体格式,结构固定,照着现有的一份复制一遍、把语言标识改掉、把正文换成本地语言,一门语言不到二十分钟。真正花时间的是找人写那几句话。

还有一个观察值得记:这份清单里有爱尔兰语这样使用人口很小的语言,却没有阿拉伯语。这说明收录与否取决于当年有没有人愿意贡献那份翻译,跟市场规模没有关系。别拿商业重要性去推断有没有现成资源。

打开它要付什么代价

好消息讲完了,讲代价。

这套机制依赖内容协商模块,也就是让服务器根据请求头挑一个语言变体。

启用它意味着多一个模块、多一层匹配开销,而且那批自带文案的语气是纯技术风格,跟品牌调性差得很远。

还有一个隐蔽的副作用:内容协商一旦打开,它的作用范围不止错误页,配置不当会影响到别的路径。

所以务实的做法是把它当成一个原型:先用它验证语言协商这条路在自己站上通不通,通了再换成自己写的文案。自定义错误页那篇技术拆解里给过一句判断,说按访客语言出对应语种会引入动态判断、小站做一版规范的英文页也够用;从纯技术角度这句话没错,但那份判断没有把多语言站算进来,下一节就来给它补一个判据。

还有一个跟性能有关的副作用:启用内容协商之后,响应里会带上一个告诉缓存按什么维度区分的头。这个头会直接影响边缘缓存的命中率,因为同一个地址被拆成了按语言分的多份缓存。

语言协商能不能救场,浏览器发过来的那个头够用吗?

请求头里确实带着语言偏好

浏览器在每次请求里都会带一个表示语言偏好的头。

它的值是一串语言标签,还带着权重,表示用户更想要哪一门。

这个值来自浏览器和操作系统的设置,不需要用户额外做什么。

服务器完全可以读它,然后挑一份对应语言的错误页出来。

听起来这条路很顺,问题出在它跟你站上的语言版本不是一回事。

实际抓一批请求会发现,多数浏览器只发两三个语言标签,权重也很简单。所以这个头的信息量比规范允许的要少得多,指望靠它做精细判断是不现实的。

浏览器偏好和市场版本是两个坐标系

这是这条路最大的坑。

一个在德国生活的土耳其人,浏览器语言可能是土耳其语,而他要买的是德国站的东西。

一个用英文系统的日本用户,浏览器发过来的是英语,他要的却是日语页面。

换句话说,请求头说的是这个人习惯读什么,你的站分的是这批货卖去哪儿。

两个坐标系经常不重合,本站在两种语言都看得懂的用户那篇里拆过这种错位,这里只补一句:错误页比普通页面更该谨慎,因为用户此刻已经处在一次挫折里,再被扔到一个他没要求的版本上,挫折会翻倍。

有个可以量化的做法:在正常页面上抽样统计请求头的首选语言与地址前缀语言的一致率。一致率高的市场可以放心用请求头兜底,一致率低的市场就别用。这个数一次统计能用很久。

匹配规则比想象中松,会挑出你没准备的那一门

还有一层技术细节值得知道。

语言标签的匹配有一套标准算法,分基本匹配和扩展匹配两种。

基本匹配允许前缀命中,也就是说请求要的是某个地区变体,服务器可能拿一个更宽的变体去顶。

这在正常页面上通常是好事,在错误页上偶尔会挑出一个你根本没审过的文件。

更常见的一种表现是权重相同的时候按优先级表挑,而优先级表是你配的,不是用户要的。所以这条路的正确用法是:只在你确实准备了那门语言的时候才让它参与协商,没准备的一律回落。

两种匹配的差别在带地区码的场合最容易咬人。用户要的是某个地区变体,你只准备了通用变体,基本匹配会把通用变体给他,这通常没问题;反过来你准备了多个地区变体而用户只要通用的,挑中哪一个就取决于优先级表。

什么时候该信这个头,什么时候该信地址

给一条能直接用的判据。

如果失效的那个地址本身带着语言前缀或者国家目录,那就按地址走,别看请求头。

地址里带的信息是确定的,它说明用户原本要去哪一版。

只有当地址完全不带语言信息时,才退回去读请求头。

这条判据的好处是它把绝大多数情况交给了确定信息,只把剩下的小部分交给猜测。对于目录形式的多语言站,这条几乎能覆盖九成的故障请求。

还有第三种情形:地址带国家不带语言,比如按国家分目录但一个国家里有两门官方语言。这时候地址只能确定国家,语言仍要靠请求头,而这恰好是双语国家最容易出错的地方。

还有一个特别值得提的场景:抓取程序发来的语言偏好通常是空的或者一个固定值。所以按请求头出语言的方案,在抓取程序那里永远走的是回落分支,它看到的始终是默认语言那一版。

一版英文错误页到底够不够用,判据是什么?

够用这个结论是在什么前提下成立的

先承认这个结论有它成立的场合。

如果你的站只有一门非英语语言,而且那个市场的英语普及率很高,那一版规范的英文错误页确实够用。

如果故障页的流量极低,低到一个月只有几十次,那投入产出也不划算。

这两个前提在很多技术文章的写作场景里是默认成立的。

问题是它们在多语言电商站上多数不成立,而不成立的方式还不止一种。

这两个前提在写技术文章的场景里天然成立,因为技术文章的读者多半在处理单语言站的配置问题。这不是作者的疏忽,是场景差异,而读的人往往不会注意到自己的场景已经不同了。

三个把它推翻的场景

第一个场景是改版。

一次品类重构或者地址结构调整,能在一周内制造出成千上万次故障请求,而且这批请求集中落在你最值钱的那批旧地址上。

第二个场景是英语普及率低的市场。越南、泰国、巴西、俄语区,一张纯英文的技术风格错误页对当地用户来说跟一张白屏差别不大。

第三个场景是信任。故障页是用户对一个陌生站点做信任判断的高危时刻,此刻出现一门外语,等于在说这个站不是给你做的。本站在落地页上那几个最像装饰的信任元素里量过这一层的分量,故障页是同一条逻辑的极端版本。

还有第四个场景:站点被外部大量引用。外部引用里的地址是别人写的,写错、写旧、带着追踪参数都很常见,这批流量落到故障页上的比例比自有流量高得多,而它们通常来自你最看重的那些来源。

按流量算这一页的价值,算法跟别的页不一样

常规做法是按页面浏览量排优先级,故障页在这个排序里永远垫底。

但故障页的价值不在它自己的浏览量上,而在它拦住了多少条本来要流失的路径。

正确的算法是看这批请求原本要去哪儿:如果它们指向的是品类页和商品页,那这一页拦的是交易意图。

做法是把故障地址按原目标页面类型分组,算出指向商品页的那部分占比。

这个占比超过三成,这一页就该按商品页的标准来做,而不是按技术页的标准。

这个占比拿起来不难:把故障地址按路径结构分类,带商品标识的归商品页,带分类路径的归品类页,其余归其他。用一条正则就能分完,几千条地址跑一次不到一分钟。

三档投入分别做到哪一档

把投入分成三档,按市场对号入座。

最低一档是一版设计过的英文页,带搜索框和主要品类入口,状态码正确。适合英语普及率高、语言版本只有一两个的站。

中间一档是按地址前缀出对应语言的静态页,每门语言一个文件,文案由本地写手写一次。适合三门以上语言、且有主力小语种市场的站。

最高一档是把故障页接回应用层,带上个性化推荐和最近浏览。这一档只在故障请求量确实很大、或者改版频繁的站上才划算。多数站停在中间那一档就够了,再往上投的边际收益掉得很快。

从第一档升到第二档的触发条件建议写死成一个数:当第二门非英语语言上线时。这个时点很好识别,也正好是问题开始成规模的时点,比按流量阈值判断更容易执行。

错误页的文案在小语种里,为什么比英语更难写?

它是全站语气要求最高的一页

这一页要在两三句话里同时完成四件事。

说清楚出了什么事,表明这是我们的问题不是你的问题,给一条出路,还不能让人更烦躁。

四件事挤在两三句话里,对措辞的精度要求比商品描述高得多。

商品描述写得平庸只是不出彩,故障页写得平庸会直接放大用户的挫折感。

而这一页恰恰是最容易被丢给机器翻译的一页,因为它字少、看着不重要、也没人愿意为它开一次审校。

这一页还有个结构性的劣势:它字太少。机器翻译在短文本上的表现明显差于长文本,因为上下文不够。全站最短的几段文字恰好是语气要求最高的几段,这个组合对机翻是最不利的。

道歉这件事在各语言里的分寸不一样

这一页的核心动作是道歉,而道歉是各语言差别最大的言语行为之一。

日语的道歉有明确的档位,档位选低了显得敷衍,选高了显得这事很严重。

德语市场对夸张的致歉措辞不太买账,直接说明情况反而更得体。

把英文那句抱歉直译过去,多数语言里会落在一个不太对的档位上。

本站在退货政策那句承诺翻完之后强度就变了里拆过这类强度漂移,故障页文案是同一类问题的短句版:句子越短,一个词的档位就越决定整句的语气。

有个能直接执行的做法:让本地写手按轻中重三档各写一版,然后你拿三版去问另外两个母语者哪一版最像正规商家会说的话。这个流程不需要你懂那门语言,也不依赖单个写手的判断。

文本膨胀在这一页格外要命

故障页的版面通常是居中一块,宽度写死。

英文原文两行的文案,翻成德语可能变成三行,翻成芬兰语更长。

普通页面上多一行没什么,故障页上多一行可能把唯一那个按钮挤出首屏。

而这一页几乎没有人会在真机上按语言逐个看过。

膨胀比例和处理办法本站在德语长词在手机上撑破版面那篇里讲过,这里只提一条针对故障页的:这一页的文案要按最长的那门语言排版,而不是按英文排版,因为它只有一个版式。

按最长语言排版的具体做法是:先让写手把所有语言版本都写出来,量一遍字符数,取最长的那一版去定版面宽度和按钮位置。之后哪怕再加语言,也在这个宽度里试排一次即可。

别在错误页上玩梗,尤其是在不是你母语的市场

英文错误页上放一句俏皮话是行业惯例,效果通常不错。

这个惯例在跨语言时的失败率高得惊人。

幽默依赖共同语境,而共同语境正是你在一个新市场里最缺的东西。

更糟的是幽默翻译得不好会读成轻佻,用户此刻本来就不高兴。

稳妥的做法是:母语市场可以玩,本地写手主动提出来的可以玩,其余一律用直白得体的说法。少一点俏皮换来的是零风险,这笔交易在故障页上是划算的。

有一个例外:品牌调性本身就建立在轻松感上、并且本地写手主动提议的,可以试。判断标准是这句俏皮话有没有经过至少两个母语者点头,而不是译者觉得可以。

本地化错误页的时候,怎么保证状态码不被改坏?

状态码和文案是两件事,改文案不该动状态码

这是这一节唯一需要记住的原则。

状态码告诉机器发生了什么,文案告诉人发生了什么。

两者可以各自本地化,但不能互相影响。

做错误页的人多数关心文案,配服务器的人多数关心状态码,两拨人交接的地方就是事故高发区。

本站在HTTP状态码那份图谱里讲过每个码该在什么场合用,这里只补跟多语言相关的那几处坑。

两拨人交接的地方建议固定成一条检查项:任何一次故障页改动,都要在合并前跑一遍状态码验证。把它挂进发布流程,比靠人记住可靠得多,因为这类改动通常不被当成有风险的改动。

最常见的一种改坏:指到外部地址就变成了跳转

这个坑写在官方文档里,但很少有人读到那一句。

服务器的错误页指令,参数如果是一个本地路径,服务器会在内部处理并保留原始状态码。

参数如果是一个完整的外部地址,服务器会改成向客户端发一次跳转。

结果是客户端收到的不再是404,而是一个跳转码,然后再收到目标页的200。

多语言站踩这个坑的概率比单语言站高得多,因为大家很自然地会想把不同语言的错误页放在各自的语言目录下,写着写着就写成了带域名的完整地址。检查方法是把配置里所有错误页指令的参数看一遍,凡是以协议开头的都要改成以斜杠开头。

另一类服务器软件上有一个形状不同但后果相同的坑:错误页指令和跳转指令写法相近,写错一个关键字就会把内部渲染变成外部跳转。检查方法一样,看配置里这一族指令的参数是不是以斜杠开头。

软404在多语言站上会多出一种成因

软404指的是页面内容说找不到,状态码却是200。

单语言站上它多半来自应用层的兜底逻辑。

多语言站上还多一种:语言回落。用户请求某个语言版本的某个页面,那门语言没有这个页面,系统悄悄回落到默认语言的同名页面并返回200。

从状态码看这是一次成功访问,从用户看这是一次内容缺失,从检索看这是一个跟默认语言页面高度相似的重复页。

这一类比普通软404更难查,因为页面本身是完整的、有内容的、有正确样式的,只是语言不对。软404怎么排查那篇给的方法在这里仍然适用,只是要多加一个筛选条件:把返回200但页面语言与地址前缀不一致的记录单独捞出来。

这类回落页还有一个连带损害:它跟默认语言的同名页面内容几乎一样,于是在跨语言重复判定上落得很难看。本来是缺一页内容,最后表现成两页互相稀释。

上线后怎么验状态码真的对

验证不能靠肉眼看页面,页面看着对状态码可能是错的。

要用能显示响应头的工具逐条请求,只看状态码那一行。

要验的清单是:每门语言各一个不存在的地址、每门语言各一个已下架商品、维护页开启时的一个正常地址。

三类各跑一遍,语言数乘以三就是要跑的条数,四门语言也就十二条。

顺手把跳转链也看一眼,故障页前面挂着一串跳转是很常见的现象,而每一跳都在消耗抓取预算。

工具上不必讲究,能显示响应头就行,命令行的请求工具或者浏览器的开发者面板都可以。要看的只有三行:状态码、内容语言、以及有没有跳转链。三行看完这条就算验过。

那些你根本改不到的错误页,该怎么处理?

边缘节点的拦截页

内容分发网络和防火墙在边缘挡下的请求,源站完全不知情。

这类页面由服务商生成,默认是英文,带着服务商自己的品牌和一串排查编号。

多数服务商提供自定义错误响应功能,允许你上传一份自己的页面。

但要注意它通常只允许一份,也就是说语言这个维度在这里又一次消失了。

务实的做法是把这一份做成不依赖语言的版本:图形化的提示、品牌标识、一个回首页的按钮,文字尽量少。文字越少,它在多少门语言下都不算错。

如果服务商允许,把这份自定义页面设成不允许索引,是一个零成本的动作。挡板页本来就不该进索引,而默认设置多半没有加这一条。

支付网关跳回来的那一页

结算失败是转化链上最贵的一次故障,而这一页经常不由你输出。

用户在网关那边失败,网关按它自己的语言设置显示一段话,然后跳回你的站。

跳回来的地址上通常带着一个错误码参数,而你的页面拿这个参数做了什么,多数团队没检查过。

能做的动作有两个:一是在接入时把语言参数显式传给网关,多数网关都有这个字段,只是接入的时候没人填;二是自己接住跳回来的错误码,用自己的语言给出一句解释,而不是原样显示网关那段话。

第一件事的性价比极高,因为它属于接口文档里明明写着、接入时图省事没填的那一类。机器不完全相信你写在页面上的语言声明那篇里记过同一个模式:问一句有没有把语言字段传给它,往往比问它怎么判断更快找到根因。

语言参数在多数网关的接口文档里叫地区或者语言环境,取值多半是标准语言标签。查的时候直接在文档里搜这个词,通常两分钟能找到,找到之后填进去就完事。

第三方组件自己弹的提示

评价插件、客服窗口、地址校验、库存查询,这些组件都会在出错时弹自己的提示。

它们的语言由组件自己的语言包决定,跟你的站没有关系。

多数组件支持传入语言参数,少数只认浏览器设置。

排查办法是把站上接入的第三方组件列一张表,逐个记录它的故障提示走哪套语言。

这张表通常十行以内,一次列完能用很久,而且它顺手回答了另一个问题:哪些组件在小语种下压根没有语言包,那几个是要考虑换掉的。

这张表还能顺手回答另一个问题:哪些组件在你的小语种上根本没有语言包。有几个组件的语言包只覆盖十几门主流语言,你要开的市场不在里面,那这个组件在这个市场上永远是英文的,该考虑换掉。

改不到的时候,能做的三件事

遇到确实改不了的,还有三个动作。

第一是减少触发。把边缘规则和防火墙规则调松一点,让本来正常的用户不要撞上挡板。

第二是缩短暴露。给这类地址加一条快速跳转,让用户停留在那一页的时间尽量短。

第三是记录频次。哪怕改不了内容,也要知道它一个月发生多少次,这个数字是将来跟服务商谈判或者换服务商的依据。

三件事都不解决语言问题,但它们把语言问题的影响面压到了最小,这在改不动的场合是唯一能做的事。

还有第四件:把这类地址从站点地图和站内链接里摘干净。改不了那一页的内容,至少可以少往那儿送人,尤其是别让自己的内链把用户和抓取程序一起送过去。

那家宠物用品站后来做了什么,波兰语那边为什么一直没事

同一套配置,两个市场结果不一样

回到开头那个案例,最让团队困惑的是配置明明是同一套。

拆开看之后原因很直白:波兰语在服务器自带的那21门语言里,越南语不在。

波兰用户的浏览器发来波兰语偏好,服务器恰好有一份波兰语的错误文档,于是挑给了他。

越南用户发来越南语偏好,服务器手上没有这门语言的变体,按优先级表回落到英语。

两个市场看到的是两张完全不同的页面,而后台配置一个字都没差。这也是为什么这类问题几乎不可能靠读配置发现,只能靠在当地网络环境里真的点一次。

确认这个差别的办法很朴素:拿两个市场的浏览器语言设置各请求一次同一个不存在的地址,把两次的响应正文存下来对比。两份不一样就说明协商在起作用,一样就说明它没起作用。

定位它花了很久,因为报表里没有这一类

找到根因之前,团队查了三个方向都不对。

先怀疑是重构后的重定向没做全,查完发现重定向覆盖率有九成以上。

再怀疑是当地网络问题,找了本地同事测速,一切正常。

又怀疑是季节性波动,拉了去年同期数据,对不上。

真正的原因躺在一个没有任何报表会统计的地方:故障页按语言的分布。所有分析工具都会告诉你404发生了多少次,没有一个会告诉你这些404里有多少张是用用户看不懂的语言写的。

第四个被排除的方向是内容质量,团队一度怀疑越南语译文不行,还专门请了第二个写手复审。复审结论是译文没问题,这一步花掉两周,而问题根本不在被审的那批页面上。

改了三处

第一处是把那份自带的多语言错误文档接上,并且为越南语补了一份,因为原厂清单里没有。

第二处是把错误页指令的参数全部改成以斜杠开头的本地路径,之前有两条写成了带域名的完整地址,正在悄悄把404变成跳转。

第三处是给故障页加了一层按地址前缀判断的逻辑:地址里带语言目录的直接用那门语言,不带的才去读请求头。

三处改动加起来不到一天,其中最花时间的是给越南语写那几句文案,因为要请写手重新想道歉的分寸。

顺带做的第四件事是给这一页配了搜索框和三个主力品类入口,这一件跟语言无关,但它把这一页从终点变成了一个岔路口。

第四处本来在计划里但最后没做:给故障页接上按浏览历史的商品推荐。没做的理由是评估之后发现这一页的停留时间太短,推荐位来不及产生作用,投入产出不划算。

结果里最有意思的是那个减法

两个月后回看,越南站的品牌词表现回到了改版前的水平。

更有意思的是另一个数字:从故障页跳回首页再离开的比例明显下降,而从故障页进入搜索的比例上来了。

也就是说这一页真正的收益不在留住多少人,在于把原本会直接关掉的那批人转成了还愿意再找一下的人。

团队原本准备的那套按用户画像推荐商品的方案最后没上,因为在这一页上,能读懂和有出路这两件事已经拿走了绝大部分收益。

这是个值得记一笔的经验:故障页的优化空间很浅,浅到做完基础的两三件事之后就基本见底了,再往上投多半是浪费。

这个结论可以直接复用到别的低频页面上:凡是用户处在挫折状态、停留时间以秒计的页面,先把能读懂和有出路做到位,别急着上个性化。个性化需要用户愿意多停一会儿,而这类页面上他不会。

把错误页的语言收成一张能照着做的清单

半天能做完的第一版

第一版的目标是止血,不追求完美。

先把最近三个月的故障地址导出前一百条,跑一遍看三层来源的分布。

再把服务器配置里的错误页指令全部检查一遍,把带域名的改成本地路径。

然后给现有的那一版错误页加上搜索框和主要品类入口,不管它是什么语言。

最后在每个语言版本的地址下各请求一个不存在的页面,截图存档。半天走完这四步,最贵的那类事故基本就堵住了。

还有第五步:把故障页从站点地图里去掉,同时确认它带着不允许索引的标记。这一步十分钟,但漏掉的话前面四步的收益会被抵消一部分。

一周能做完的完整版

完整版要多做四件事。

按地址前缀出对应语言的错误页,每门语言一个静态文件。

把文案交给本地写手写一次,重点是道歉那一句的分寸和出路那一句的措辞。

把第三方组件的故障提示列成表,逐个确认语言参数有没有传。

把边缘节点的自定义错误响应做成一份少文字的通用版本。

四件事里最花时间的是第二件,因为它需要排期和审校;其余三件都是配置层动作,一个人一天能推完。

排期上建议把写文案那一件先启动,因为它是唯一需要等别人的动作。其余三件都可以在等文案的同时并行推,等文案到了直接填进已经搭好的文件里。

上线前的六项检查

照着这六条走一遍再发布。

每门语言的不存在地址返回的是404而不是跳转码。

维护期间返回的是503并且带着重试提示头。

故障页上的文字在最长的那门语言下没有把按钮挤出首屏。

语言回落的场景下没有产生返回200的伪页面。

故障页本身没有被索引,也没有出现在站点地图里。

边缘服务商那一份自定义页面已经上传并且验证过生效。六条里前两条最容易被忽略,也最贵。

验证工具上不必新增:状态码用能看响应头的请求工具,版面用真机加浏览器的设备模拟,索引状态用站长工具的地址检查。三样都是现成的,六条检查一个人一小时能跑完。

六条之外还有一条推荐动作:把这次的检查结果按语言存成一张表,下次改版之前先看它。故障页的问题几乎都是改版带出来的,而改版的时候没人会想起上一次是怎么处理的。

三条该让你停下来的反信号

最后给三条别做的信号。

第一,如果你的站只有一门非英语语言,而且那个市场英语普及率很高,做到第一版就够,别往下投。

第二,如果故障请求量一个月只有几十次,而且没有改版计划,这件事排不进优先级。

第三,如果为了做语言协商要引入一整套动态判断,而你的站是纯静态托管,那就用按地址前缀出静态文件那一档,别为了这一页把架构改了。

判断顺序永远是先看这一页拦的是不是交易意图,再看做到哪一档。拦的是交易意图就值得做,拦的是爬虫和垃圾请求就不值得。

还有第四条:如果这批故障请求里绝大多数来自爬虫和扫描器而不是真实用户,那么把力气花在减少这类请求上比花在美化这一页上划算。先看来源构成,再决定要不要做。

最后提一句判断顺序上的经验:这一页的投入产出曲线很陡,前面两三件事拿走绝大部分收益,之后迅速变平。所以正确的策略不是做得多完美,而是尽早做完那两三件,然后转身去做别的。

常见问题解答

多语言站的404页面,到底要不要按语言做几份?

看这批故障请求原本要去哪儿。把最近三个月的故障地址按原目标页面类型分组,如果指向商品页和品类页的占三成以上,那这一页拦的是交易意图,值得按语言做。只有一门非英语语言、且那个市场英语普及率很高的站,一版设计过的英文页加上搜索框和品类入口就够了。判断顺序是先看拦的是什么,再看做到哪一档。

服务器自带的多语言错误文档,直接用行不行?

可以当原型用,不建议当成品。它附带的那批文案是纯技术风格的,跟品牌调性差得很远,落款还带着软件版本号。更实际的限制是它的语言清单只有21门,阿拉伯语、越南语、泰语、印地语一门都没有。正确的用法是先用它验证语言协商在自己站上通不通,通了再把文案换成自己写的,缺的语言自己补一份文件。

能不能直接读浏览器发来的语言偏好来决定错误页语言?

能,但它应该是备选而不是首选。浏览器偏好说的是这个人习惯读什么,你的站分的是这批货卖去哪儿,两个坐标系经常不重合。更稳的判据是:失效的那个地址如果带着语言前缀或者国家目录,就按地址走,地址里的信息是确定的;只有地址完全不带语言信息时,才退回去读请求头。目录形式的多语言站,这条能覆盖九成故障请求。

把错误页指到另一个语言目录,会不会影响状态码?

会,而且这是多语言站最容易踩的一个坑。服务器的错误页指令参数如果是本地路径,服务器内部处理并保留原始状态码;如果写成带域名的完整地址,服务器会改成向客户端发一次跳转,客户端收到的就不再是404。检查办法是把配置里所有错误页指令的参数看一遍,凡是以协议开头的一律改成以斜杠开头。

语言回落导致的软404,怎么跟普通软404分开?

加一个筛选条件:把返回200但页面实际语言与地址前缀不一致的记录单独捞出来。这一类比普通软404难查,因为页面本身完整、有内容、样式也正常,只是语言不对。它的成因是用户请求某语言版本的某页面,那门语言没有这一页,系统悄悄回落到默认语言并返回200,于是从状态码看是一次成功访问。

边缘节点和防火墙挡下的页面改不了,还能做什么?

三件事。第一是减少触发,把边缘规则和防火墙规则调松,别让正常用户撞上挡板。第二是缩短暴露,给这类地址加一条快速跳转。第三是记录频次,哪怕内容改不了也要知道它一个月发生多少次,这个数字是将来换服务商的依据。如果服务商允许上传一份自定义页面,就把它做成少文字的图形版本,文字越少在多少门语言下都不算错。

错误页上的文案可以用机器翻译吗?

这是全站最不该用机器翻译的几页之一。它要在两三句话里同时说清出了什么事、表明责任在我们、给一条出路、还不能让人更烦躁,对措辞精度的要求比商品描述高。而道歉又恰好是各语言差别最大的言语行为之一,档位选错比不道歉更糟。句子越短,一个词的档位就越决定整句语气,这一页正好全是短句。

权威参考资料

分享到
标签
版权声明

本文标题:《用户撞上404的那一刻,请求已经不在你的应用里了,本地化也就管不到》

本文链接:https://zhangwenbao.com/minor-language-error-page-fallback-language.html

版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交