用 JavaScript 阅读我的博客
原文由 Michael Lynch 于 发布,订阅该博客
现在你可以用客户端 JavaScript 来阅读我的博客了。我也不知道你为什么会想这么做,但确实可以。
比如,你想在自己的网站上加一个博客导航,列出你喜欢的博客的最新文章,但又不想在服务端去抓取。如果你想用 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 订阅源设置跨源资源共享(CORS)HTTP 标头。通常,阻止不同网站之间通过客户端 JavaScript 读取彼此内容的,正是同源策略。
同源策略规定,每个站点(源)只能读取与其自身域名关联的资源。举个例子,如果你访问了我在 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 订阅源做了什么有意思的事情,请告诉我。
随机一篇博客
评论
登录后参与讨论