【捉虫记】第2期 为什么有些RSS订阅链接,在浏览器上打开会显示乱码
笔者在做RSS订阅时,发现了部分订阅链接在浏览器上打开后显示乱码。并且经过测试后,发现这个问题并非编码错误那么简单。遂做记录
问题是这样的,拿到一个订阅链接比如https://security.tencent.com/index.php/feed/blog/0
,在浏览器上访问,会看到如下图效果(乱码)
在2025年的今天,除了程序员,应该很少有人能直接遇到阅读内容乱码的情况,但恰恰如上的链接,在浏览器访问时内容就会显示乱码。
因为xml作为rss的信息载体,需要通过专用RSS订阅器解析后才能被用户所阅读。当就这个方面讲,讨论RSS在浏览器上打开乱码是无意义的。所以本文要探讨的是,为什么XML这么成熟的文本格式,在浏览器上打开有可能乱码?
RSS一种信息聚合协议,可以让用户高效的订阅特定信息。RSS和html一样都是通过http进行传输,不一样的是,头部信息Content-Type的内容不同,如下所示
而对于RSS,主流有三种Content-Type:application/rss+xml
、application/atom+xml
和application/xml
我们拿几个rss链接来测试,并取出其响应头的Content-Type
所有数据都在chrome和edge(都基于 Chromium)上测试,Firefox因为会直接把此类MIME直接下载为文件而排除在外
RSS源 | 链接 | Content-Type | 测试结果 |
---|---|---|---|
阮一峰的网络日志 | http://www.ruanyifeng.com/blog/atom.xml | application/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/0 | application/rss+xml | 乱码 |
其中只有腾讯安全响应中心的显示内容是乱码,如下图所示,xml中已经指定了编码为utf-8
从上面表格一对比,貌似问题不是出在xml上,而是响应头Content-Type内容少了charset编码
通过本地Python+Bottle进行模拟测试得到如下结果
的确通过添加charset编码可以解决
那这里问题就来了,在Content-Type缺少编码的情况下,为什么浏览器不会从xml去获取编码?
如果细心留意,可以发现,其实application/rss+xml
类型的响应内容,并不会被浏览器认为是xml,而是当成了纯文本进行展示
我们可以通过一个真正的xml去对比
看到了吗?所以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+bottle
对tom+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
,才能避免浏览器猜错编码导致乱码
这里顺带提一下Opera,现在的Opera同样基于Chromium开发,同时它自身支持RSS订阅(会把RSS订阅链接解析成新闻加入到个人化新闻页面中)
Opera不支持解析rss+xml和atom+xml,只支持xml(即content-type
为application/xml
)
最让人绷不住的是,Opera解析XML乱成一锅粥。下面分别是用不同编码数据流,响应头指定编码,XML指定编码,只有数据流编码=GBK和XML编码encoding='GBK'同时满足时
才不会出现乱码,其他编码,要不就是标题乱码,要不就是内容乱码,再不就是全部乱码。显然Opera自从退出国内市场后,就不再进行完整的国际化测试了
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
评论已关闭