笔者在做RSS订阅时,发现了部分订阅链接在浏览器上打开后显示乱码。并且经过测试后,发现这个问题并非编码错误那么简单。遂做记录

问题是这样的,拿到一个订阅链接比如https://security.tencent.com/index.php/feed/blog/0,在浏览器上访问,会看到如下图效果(乱码)

2025-07-08 13 26 41.png

在2025年的今天,除了程序员,应该很少有人能直接遇到阅读内容乱码的情况,但恰恰如上的链接,在浏览器访问时内容就会显示乱码。

因为xml作为rss的信息载体,需要通过专用RSS订阅器解析后才能被用户所阅读。当就这个方面讲,讨论RSS在浏览器上打开乱码是无意义的。所以本文要探讨的是,为什么XML这么成熟的文本格式,在浏览器上打开有可能乱码?

RSS一种信息聚合协议,可以让用户高效的订阅特定信息。RSS和html一样都是通过http进行传输,不一样的是,头部信息Content-Type的内容不同,如下所示

2025-07-19 15 25 49.png

而对于RSS,主流有三种Content-Type:application/rss+xmlapplication/atom+xmlapplication/xml

我们拿几个rss链接来测试,并取出其响应头的Content-Type

所有数据都在chrome和edge(都基于 Chromium)上测试,Firefox因为会直接把此类MIME直接下载为文件而排除在外
RSS源链接Content-Type测试结果
阮一峰的网络日志http://www.ruanyifeng.com/blog/atom.xmlapplication/xml
IT之家https://www.ithome.com/rss/text/xml; charset=utf-8
小众软件https://feeds.appinn.com/appinns/application/rss+xml; charset=utf-8
腾讯安全响应中心https://security.tencent.com/index.php/feed/blog/0application/rss+xml乱码

其中只有腾讯安全响应中心的显示内容是乱码,如下图所示,xml中已经指定了编码为utf-8

2025-07-08 13 26 41.png

从上面表格一对比,貌似问题不是出在xml上,而是响应头Content-Type内容少了charset编码

通过本地Python+Bottle进行模拟测试得到如下结果

的确通过添加charset编码可以解决

2025-07-08 14 34 31.png

那这里问题就来了,在Content-Type缺少编码的情况下,为什么浏览器不会从xml去获取编码?
如果细心留意,可以发现,其实application/rss+xml类型的响应内容,并不会被浏览器认为是xml,而是当成了纯文本进行展示
我们可以通过一个真正的xml去对比

2025-07-08 14 45 43.png

看到了吗?所以MIME=application/rss+xml的响应内容,就算是规范的XML,里面写的编码,都被浏览器当做纯文本展示

那是不是rss+xml这个标准的实现有问题?经过查询,尽管RSS规范(https://www.rssboard.org/rss-mime-type-application.txt)约定rss的MIME为pplication/rss+xml,但是在MIME的标准(https://www.iana.org/assignments/media-types/media-types.xhtml)里,并没有找到,也就是MIME目前还不认可rss+xml。问题会在这里么?
并不是,因为在MIME的标准里,有atom+xml这一类型,我使用Python+bottletom+xml类型进行了测试,发现结论和rss+xml完全一致

所以真正的问题在于浏览器对*+xml的实现,浏览器并不把基于xml进行数据格式规约的*+xml当做xml,可能是基于XMl扩展类型太多(光MIME已规范的就有452种),其中部分还包含可执行代码(比如xml-patch+xml),这会导致安全隐患。所以对于XHTML+XML、XML两者外的其他XML扩展,一律当纯文本展示

经过多组组合测试,结论如下

对于响应头是application/xml的,浏览器可以完美进行解码。
但是对于application/*+xml,浏览器按纯文本展示。而上文说的那个乱码,即是浏览器猜测编码不对导致的。所以如果要用*+xml,一定要传递编码,如application/atom+xml;charset=utf-8,才能避免浏览器猜错编码导致乱码

2025-07-08 15 10 35.png

这里顺带提一下Opera,现在的Opera同样基于Chromium开发,同时它自身支持RSS订阅(会把RSS订阅链接解析成新闻加入到个人化新闻页面中)
Opera不支持解析rss+xml和atom+xml,只支持xml(即content-typeapplication/xml

最让人绷不住的是,Opera解析XML乱成一锅粥。下面分别是用不同编码数据流,响应头指定编码,XML指定编码,只有数据流编码=GBK和XML编码encoding='GBK'同时满足时才不会出现乱码,其他编码,要不就是标题乱码,要不就是内容乱码,再不就是全部乱码。显然Opera自从退出国内市场后,就不再进行完整的国际化测试了

2025-07-08 16 05 48.png