如何在 JavaScript 中获取和解析 RSS Feed

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

假设您有一个 RSS Feed 像这样。目标是请求该 RSS Feed,解析它,并对其中的数据执行一些有用的操作。RSS 是 XML,而 XML arguably 比 JSON 不那么容易处理。虽然许多 API 提供 JSON 响应,但对于 RSS 来说并不常见,尽管 它确实存在

让我们开始吧。

首先,最好 验证 Feed。这样,您至少可以知道您正在使用有效的响应(解析可能会在无效的响应上失败)。

然后,我们需要向 RSS Feed 所在的 URL 发出网络请求。让我们使用 JavaScript 原生的 fetch API,因为这是最广泛适用的。它肯定可以在浏览器中工作,而且看起来 Node 有 一个非常流行的实现

我们将执行以下操作

  1. 调用 URL
  2. 首先将响应解析为文本
  3. 然后使用 DOMParser() 解析文本
  4. 然后像使用普通 DOM 引用一样使用数据
const RSS_URL = `https://codepen.io/picks/feed/`;

fetch(RSS_URL)
  .then(response => response.text())
  .then(str => new window.DOMParser().parseFromString(str, "text/xml"))
  .then(data => console.log(data))

我们可以在该函数中完成我们的工作。RSS 类似于 HTML,因为它嵌套了元素。我们的数据将类似于以下内容

<rss>
  <channel>
    <title>Feed Title</title>
    <item>
       <link>https://codepen.io/billgil/pen/ewqWzY</link>
       <title>A sad rain cloud</title>
       <dc:creator>Bill Gilmore</dc:creator>
    </item>
    <!-- a bunch more items -->
  </channel>
</rss>

因此,我们可以针对这些 <item> 元素使用 querySelectorAll 并循环遍历它们以执行我们想要的操作。在这里,我将制作一堆 <article> 元素作为模板,然后将其放置到网页上

fetch(RSS_URL)
  .then(response => response.text())
  .then(str => new window.DOMParser().parseFromString(str, "text/xml"))
  .then(data => {
    console.log(data);
    const items = data.querySelectorAll("item");
    let html = ``;
    items.forEach(el => {
      html += `
        <article>
          <img src="${el.querySelector("link").innerHTML}/image/large.png" alt="">
          <h2>
            <a href="${el.querySelector("link").innerHTML}" target="_blank" rel="noopener">
              ${el.querySelector("title").innerHTML}
            </a>
          </h2>
        </article>
      `;
    });
    document.body.insertAdjacentHTML("beforeend", html);
  });

这是一个工作演示

我一直认为 jQuery 构成一个不错的 Ajax 库,而且它还提供了一些辅助工具。以下是在 jQuery 中执行此操作的方法。

const RSS_URL = `https://codepen.io/picks/feed/`;

$.ajax(RSS_URL, {
  accepts: {
    xml: "application/rss+xml"
  },

  dataType: "xml",

  success: function(data) {
    $(data)
      .find("item")
      .each(function() {
        const el = $(this);

        const template = `
          <article>
            <img src="${el.find("link").text()}/image/large.png" alt="">
            <h2>
              <a href="${el
                .find("link")
                .text()}" target="_blank" rel="noopener">
                ${el.find("title").text()}
              </a>
            </h2>
          </article>
        `;

        document.body.insertAdjacentHTML("beforeend", template);
      });
  }
});

如果您要在生产站点上真正执行此操作,我会说依赖第三方 API(我认为 RSS 是 API)来呈现站点上的重要内容有点奇怪。我可能会在某种计时器(CRON)上服务器端发出请求,对其进行缓存,然后让您的前端使用来自该缓存的数据。更安全且更快。