用 JavaScript 读取我的博客
现在,你可以用客户端 JavaScript 读取我的博客了。我不确定你为什么会想这么做,但你确实可以。
也许你想在自己的网站上添加一个博客列表(blogroll),展示来自你喜欢的博客的最新文章,但又不想在服务器端抓取这些内容。如果你想用 JavaScript 显示我最近五篇文章的标题,可以这样写:
fetch("https://mtlynch.io/index.xml")
.then((response) => response.text())
.then((str) => new DOMParser().parseFromString(str, "application/xml"))
.then((data) => {
const articles = [...data.querySelectorAll("item")].map((item) => ({
title: item.querySelector("title").textContent,
date: new Date(item.querySelector("pubDate").textContent),
}));
// Sort articles by date, newest to oldest.
articles.sort((a, b) => b.date - a.date);
// Print the titles of the 5 most recent articles.
articles.slice(0, 5).forEach((article) => console.log(article.title));
});上面的代码会输出如下内容:
Refactoring English: Month 10
Get xkcd Cartoons at 2x Resolution
List of 2x-resolution xkcd Cartoons
I Once Appeared in The Old New Thing
Refactoring English: Month 9这个想法来自 Simon Willison(西蒙·威利森)最近在 Lobsters 上的一条评论。
我是如何让 JavaScript 读取我的网站的?
要启用 JavaScript 访问,我唯一需要修改的就是为我的 RSS 订阅源设置跨域资源共享(Cross-Origin Resource Sharing, CORS)HTTP 头。通常,阻止不同网站之间用客户端 JavaScript 读取彼此内容的是同源策略(same-origin policy)。
同源策略规定,每个站点(源,origin)只能读取与自己域名相关联的资源。所以,如果你访问我的博客 mtlynch.io,而我的页面里有一段 JavaScript 试图从 chase.com 读取你的银行余额,同源策略就会禁止我页面上的 JavaScript 访问这些信息。
为了让其他网站能通过 JavaScript 读取我的博客,我必须为博客的 RSS 订阅源设置 CORS 头。这个博客是一个静态站点,目前托管在 Netlify 上,所以我需要修改 Netlify 的配置文件,为我的 RSS 订阅源 URL指定 CORS 头:
[[headers]]
for = "/index.xml"
[headers.values]
Access-Control-Allow-Origin = "*"
Access-Control-Allow-Methods = "GET, HEAD, OPTIONS"
Access-Control-Allow-Headers = "Content-Type"可能出什么问题?
CORS 是一种安全机制,而对于面向互联网的站点放松安全限制,我总是保持应有的谨慎。不过我花了一段时间评估风险,在我的情况下,我认为没有任何实质性的风险。
攻击者能否窃取秘密数据?
同源策略的意义在于:如果用户在站点 A 上有敏感数据,那么站点 B 无法访问其中任何内容,除非站点 A 明确授权。
我的博客是一个没有任何秘密信息的静态站点。我访问 mtlynch.io 时看到的内容,和其他所有人看到的完全一样。因此,即使攻击者诱导我在第三方网站上运行恶意 JavaScript,这些代码也无法滥用我在自己博客上的权限,因为我在这里根本没有任何特殊权限。
我确实使用 TalkYard 来嵌入评论系统,并且在那里拥有管理员权限,但我的 RSS 订阅源的 CORS 设置并不会影响 TalkYard。
攻击者能否对我发起 DDoS 攻击?
起初,我以为攻击者可能会滥用 CORS 设置来对我的站点发起 DDoS 攻击。如果攻击者让数百万人访问一个页面,而该页面在后台用 JavaScript 不断请求我的 RSS 订阅源,那会怎么样?
后来我意识到,这种 DDoS 攻击本来就是可行的。CORS 只控制第三方域名能否读取请求的结果,但并不会从一开始就阻止请求。无论 CORS 设置如何,任何域名都可以向任何其他域名发起 GET 和 POST 请求。
攻击者能否冒充我的网站?
我考虑过的另一种攻击是冒充。访问者可以访问 evil.example.com,那里的服务器可以返回一段 JavaScript,在访问者的浏览器中重建我的博客,而地址栏仍然显示 evil.example.com。
这种攻击确实可行,但无论我的 CORS 设置如何,冒充我的博客都有更简单的办法。冒充者可以运行一个 HTTP 代理,把请求转发到我的博客,这是一种更简单的冒充方式。或者,他们也可以直接抓取我的站点并托管到别的地方。
为什么要允许 JavaScript 读取我的博客?
没有人要求我为 RSS 订阅源启用 CORS,所以我不确定它是否真的对任何人有帮助。但我热爱开放的互联网,而这是让其他网站与我的站点互通的一种有趣方式,所以我想,为什么不呢?
如果你因为这个改动而对我的 RSS 订阅源做了什么有趣的事情,欢迎告诉我。
随机一篇博客