如何访问 Web 订阅源 (HTML)

[ 本文适用于编写 Windows 运行时应用的 Windows 8.x 和 Windows Phone 8.x 开发人员。如果你要针对 Windows 10 进行开发,请参阅 最新文档 ]

本主题显示如何在你的 Windows 运行时应用中使用 Windows.Web.Syndication 命名空间中的类检索和显示 Web 订阅源。

先决条件

以下示例使用 JavaScript,且基于综合示例。 有关创建使用 JavaScript 的 Windows 运行时应用的常规帮助,请参阅创建第一个采用 JavaScript 的 Windows 运行时应用。此外,在本主题中使用 JavaScript Promise 来完成异步操作。有关此编程模式的详细信息,请参阅在 JavaScript 中使用 Promise 进行异步编程

为了使你的 Windows 运行时应用能够使用网络,你必须设置在项目 Package.appxmanifest 文件中所需的任何网络功能。 如果你的应用需要作为客户端连接到 Internet 上的远程服务,则“Internet (客户端)”功能是必需的。如果应用需要作为客户端连接到家庭网络或工作网络上的远程服务,则“家庭/工作网络”****功能是必需的。有关详细信息,请参阅如何设置网络功能

说明

检索来自 Web 订阅源的综合内容

现在,我们将查看演示如何检索订阅源然后显示订阅源包含的每个单个项的某些代码。在我们可以配置和发送请求前,我们将定义一些将在操作期间使用的变量,并初始化 SyndicationClient 的实例,该实例定义我们将用于检索和显示订阅源的方法和属性。

如果传递给 Uri 构造函数的 uriString 不是有效 URI,该构造函数将引起异常。因此,我们使用 try/catch 块验证 uriString

var currentFeed = null;
var currentItemIndex = 0;
        
var client = new Windows.Web.Syndication.SyndicationClient();

// The URI is validated by catching exceptions thrown by the Uri constructor.
var uri = null;
try {
    uri = new Windows.Foundation.Uri(uriString);
} catch (error) {
    WinJS.log && WinJS.log("Error: Invalid URI");
    return;
}

接下来,我们通过设置所有需要的服务器凭据(serverCredential 属性)、代理凭据(proxyCredential 属性)和 HTTP 标头(setRequestHeader 方法)来配置请求。 已配置基本请求参数,即有效的 Uri 对象,它是使用应用提供的订阅源 URI 字符串创建的。然后,Uri 对象将传递到 retrieveFeedAsync 函数以请求订阅源。

假设所需订阅源内容已返回,代码将在每个订阅源项上循环访问,调用 displayCurrentItem(将在下面定义),以通过 UI 以列表形式显示这些项及其内容。

当你调用大部分异步网络方法时,必须编写代码以处理异常。异常处理程序可以检索关于异常原因的更详细的信息,以更好地了解此次失败,并作出适当的判定。有关详细信息,请参阅如何处理网络应用中的异常

如果不能与 HTTP 服务器建立连接,或者 Uri 对象没有指向有效的 AtomPub 或 RSS 订阅源,retrieveFeedAsync 方法会引发异常。如果发生错误,示例代码使用 onError 函数捕捉任何异常,并打印出关于异常的更详细的信息。

function onError(err) {
    WinJS.log && WinJS.log(err, "sample", "error");

    // Match error number with a ErrorStatus value.
    // Use Windows.Web.WebErrorStatus.getStatus() to retrieve HTTP error status codes.
    var errorStatus = Windows.Web.Syndication.SyndicationError.getStatus(err.number);
    if (errorStatus === Windows.Web.Syndication.SyndicationErrorStatus.invalidXml) {
        displayLog("An invalid XML exception was thrown. Please make sure to use a URI that points to a RSS or Atom feed.");
    }
}

// Retrieve and display feed at given feed address.
function retreiveFeed(uri) {

    // Although most HTTP servers do not require User-Agent header, 
    // others will reject the request or return a different response if this header is missing.
    // Use the setRequestHeader() method to add custom headers.
    client.setRequestHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");

    client.retrieveFeedAsync(uri).done(function (feed) {
        currentFeed = feed;

        WinJS.log && WinJS.log("Feed download complete.", "sample", "status");

        var title = "(no title)";
        if (currentFeed.title) {
            title = currentFeed.title.text;
        }
        document.getElementById("CurrentFeedTitle").innerText = title;

        currentItemIndex = 0;
        if (currentFeed.items.size > 0) {
            displayCurrentItem();
        }

        // List the items.
        displayLog("Items: " + currentFeed.items.size);
     }, onError);
}

在上面步骤中,retrieveFeedAsync 返回请求的订阅源内容,并且示例代码将在可用的订阅源项上实施循环访问。这些项的每个项将使用 SyndicationItem 对象表示,其中包含相关联合标准(RSS 或 Atom)提供的所有项属性和内容。 在以下示例中,我们将看到作用于每个项和通过各种命名的 UI 元素显示其内容的 displayCurrentItem 函数。

function displayCurrentItem() {
    var item = currentFeed.items[currentItemIndex];

    // Display item number.
    document.getElementById("Index").innerText = (currentItemIndex + 1) + " of " + currentFeed.items.size;

    // Display title.
    var title = "(no title)";
    if (item.title) {
        title = item.title.text;
    }
    document.getElementById("ItemTitle").innerText = title;

    // Display the main link.
    var link = "";
    if (item.links.size > 0) {
        link = item.links[0].uri.absoluteUri;
    }

    var link = document.getElementById("Link");
    link.innerText = link;
    link.href = link;

    // Display the body as HTML.
    var content = "(no content)";
    if (item.content) {
        content = item.content.text;
    }
    else if (item.summary) {
        content = item.summary.text;
    }
    document.getElementById("WebView").innerHTML = window.toStaticHTML(content);

如上面所述,根据用于发布订阅源的不同订阅源标准(RSS 或 Atom),SyndicationItem 对象所表示的内容类型会有所不同。例如,Atom 订阅源能提供 contributors 的列表,但 RSS 订阅源不能。但是,任一标准均不支持的包含在订阅源项中的扩展元素(例如 Dublin Core 扩展元素)可以使用 SyndicationItem.elementExtensions 属性进行访问并随后显示,如以下示例代码所示:


    // displayCurrentItem function continued
    var bindableNodes = [];
    for (var i = 0; i < item.elementExtensions.size; i++) {
        var bindableNode = {
            nodeName: item.elementExtensions[i].nodeName,
             nodeNamespace: item.elementExtensions[i].nodeNamespace,
             nodeValue: item.elementExtensions[i].nodeValue,
        };
        bindableNodes.push(bindableNode);
    }

    var dataList = new WinJS.Binding.List(bindableNodes);
    var listView = document.getElementById("extensionsListView").winControl;
    WinJS.UI.setOptions(listView, {
        itemDataSource: dataList.dataSource

    });
}

摘要和后续步骤

在本主题中,我们检索了与所提供 URI 关联的订阅源,并且逐项显示了订阅源内容。

有关更多高级功能,例如添加、编辑和删除 Web 订阅源中的条目,请参阅如何管理 Web 订阅源条目

相关主题

其他

使用 JavaScript 中的 Promises 进行异步编程

如何设置网络功能

如何处理网络应用中的异常

如何管理 Web 订阅源条目

使用 JavaScript 的 Windows 运行时应用的路线图

参考

SyndicationClient

SyndicationItem

Windows.Web.AtomPub

Windows.Web.Syndication

示例

AtomPub 示例

综合示例