我们中的许多人都在互联网上有许多“家”。我个人使用 Twitter、Flickr、ScrnShots 和 Facebook。这些网络服务足够酷,可以提供与它们交互并从中提取数据的方法,甚至不必访问网站本身。这被称为 API(或应用程序编程接口)。

你可以将 API 想象成类似于 RSS Feed。如果你通过像 Google Reader 这样的 Feed 阅读器阅读 CSS-Tricks,你会知道你甚至不需要访问该网站就可以阅读我的内容,因为这些数据正在通过另一种方式提供。在 RSS 的情况下,它是一个以非常特定方式格式化的 XML 文件。API 通常以 XML 格式提供,格式取决于特定应用程序认为对你最有用的方式。XML 很酷,但就像 HTML 一样,它需要在你可以真正使用它之前进行解析。JSON 就出现了。
JSON(JavaScript 对象表示法)是如今所有流行应用程序与其 API 一起提供的,作为 XML 的替代方案。JSON 的酷点在于你不需要像解析 XML 一样解析它。你从 JSON 调用获得的数据作为对象返回,它已经准备好让你使用它。注意:如果这个解释不准确或不好,请随时更正我。
使用 API(jQuery 和 JSON)
jQuery 提供了一种非常简单的方法来检索这些 JSON 对象
$.getJSON('http://url-to-api.com', function(data){
$.each(data, function(index, item){
// do stuff with each item
});
});
上面的代码访问了提供的 URL(你需要将它替换为指向真实 API 的真实 URL,该 API 当然会输出真实的 JSON),然后遍历每个“项”,并让你有机会对该项做一些操作。我说是“项”,因为虽然这是 API 使用的常见名称,但并不总是这样,你需要在这里具体准确,因为 JSON 在错误处理方面提供的帮助非常少。
将内容插入页面
另一个使用 jQuery 的原因是因为它如何使动态将 HTML 插入页面。让我们看看从 Twitter 抓取最近“推文”的代码示例,然后使用内置的 jQuery 函数 append() 将它们放到页面上。
$.getJSON('https://api.twitter.com/1/statuses/user_timeline/chriscoyier.json?count=10&include_rts=1&callback=?', function(data){
$.each(data, function(index, item){
$('#twitter').append('<div class="tweet"><p>' + item.text + '</p><p>' + item.created_at + '</p></div>');
});
});
这将在页面上(在 ID 为“twitter”的父 div 内)放置一个新的 class 为“tweet”的 div,用于对象中的每个“项”。注意 URL 中的“count”变量,这是 Twitter 提供的。它设置为 10,这将返回 10 个项,因此页面上将有 10 个 div。在这些 div 内,我们有两个段落元素。一个是“item.text”,另一个是“item.created_at”。它们将是我的最后一条推文的实际文本以及我提交它的时间。
一个项产生的 HTML 示例
<div class="tweet">
<p>I wish position: relative; worked for table cells =P</p>
<p>1 day ago</p>
</div>
现在看起来更像了!我们可以使用我们的 CSS 技能根据需要对其进行样式设置。也许是这样的
.tweet {
padding: 10px;
margin: 5px 0;
background: url(images/transpOrange25.png);
}
扩展想法
让我们在页面上创建三个 div,一个用于 Flickr,一个用于 Twitter,一个用于 ScrnShots。然后我们将使用 jQuery + JSON 技术来填充它们。
基础 HTML
<body>
<div id="page-wrap">
<div id="flickr">
<h1>Flickr Photos</h1>
</div>
<div id="twitter">
<h1>Twitter Updates</h1>
</div>
<div id="scrnshots">
<h1>Latest ScrnShots</h1>
</div>
</div>
</body>
现在以下是用于拉取并追加来自所有三个服务的全部数据的 jQuery 代码
<script type="text/javascript" src="js/jquery-1.2.6.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?ids=52723107@N00&lang=en-us&format=json&jsoncallback=?", function(data){
$.each(data.items, function(index, item){
$("<img/>").attr("src", item.media.m).appendTo("#flickr")
.wrap("<a href='" + item.link + "'></a>");
});
});
$.getJSON('http://twitter.com/status/user_timeline/chriscoyier.json?count=10&callback=?', function(data){
$.each(data, function(index, item){
$('#twitter').append('<div class="tweet"><p>' + item.text.linkify() + '</p><p>' + relative_time(item.created_at) + '</p></div>');
});
});
$.getJSON("http://www.scrnshots.com/users/chriscoyier/screenshots.json?callback=?", function(screenshots){
$.each(screenshots, function(index, screenshot){
$("#scrnshots").append("<a href='" + screenshot.url + "'><img src='" + screenshot.images.small + "' /></a>");
});
});
});
</script>
清理 Twitter
Twitter API 吐出的“原始”数据有两个小问题。
- 链接以“失效”形式出现。完整的 URL 在那里,但它只是文本,而不是真正的锚链接。
- 日期以难看的毫秒时间戳形式出现,而不是像“2 天前”这样友好的可读文本。
我挖出了两个小 JavaScript 函数来解决这些问题。
Linkify
String.prototype.linkify = function() {
return this.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/, function(m) {
return m.link(m);
});
};
relative_time
function relative_time(time_value) {
var values = time_value.split(" ");
time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
var parsed_date = Date.parse(time_value);
var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
delta = delta + (relative_to.getTimezoneOffset() * 60);
var r = '';
if (delta < 60) {
r = 'a minute ago';
} else if(delta < 120) {
r = 'couple of minutes ago';
} else if(delta < (45*60)) {
r = (parseInt(delta / 60)).toString() + ' minutes ago';
} else if(delta < (90*60)) {
r = 'an hour ago';
} else if(delta < (24*60*60)) {
r = '' + (parseInt(delta / 3600)).toString() + ' hours ago';
} else if(delta < (48*60*60)) {
r = '1 day ago';
} else {
r = (parseInt(delta / 86400)).toString() + ' days ago';
}
所以现在,你不再只在 append 语句中放置“item.text”,而是可以放置“item.text.linkify()”。同样,你也不再放置“item.created_at”,而是可以放置“relative_time(item.created_at)”。
感谢
来自 Ralph Whitbeck 的“linkify”和“relative_time”函数。
感谢 Greg Bell 为我整理 ScrnShots API!
非常酷的帖子,谢谢!
有没有什么方法可以用于 DeviantArt?
还没有,有一些关于 dA 即将推出 API 的传言。但我最近还没有看到任何消息。
@Majesticskull,如果它有 RSS 输出,你可以始终使用类似 simplepie 的东西来解析它。
很棒的作品,我最近一直在想为我自己创建一个自动更新的主页,所以这些信息肯定会帮助我,我现在唯一需要做的就是更多地参与社交媒体网站!
很棒的教程,有什么技巧可以将来自任何 RSS Feed 的信息直接加载到我的 HTML 中?例如,将来自我的 WordPress 博客的 RSS Feed 加载到我的 HTML 网站上?
@Thomas – 正如 Tim 之前提到的,如果你只需要解析 RSS 以插入页面,SimplePie 是最佳选择。我在几周前的 iPhone/移动界面文章中讨论过如何使用它。
有一些社交网络聚合器,比如 FriendFeed (http://friendfeed.com/) 和 Soup (http://www.soup.io/),它们可以为你完成这类事情,然后提供自己的 API,这样你就可以将“lifestream”嵌入到你的博客、Facebook 个人资料等中。你没有相同的细粒度控制权,但它们易于设置和使用。
随着越来越多的社交网络不断出现,能够创建自己的个人门户是一个好主意。我唯一担心的是要依赖这些服务保持正常运行(咳嗽 Twitter 咳嗽),以免页面停滞或崩溃。
很棒的帖子!我一直想更好地展示我的 Twitter 和 Flickr 更新,这将有所帮助。
我很久以前就有了,使用 magpieRSS 和一些 php 构建的。
http://status.jaredzimmerman.com
嘿,克里斯!教程不错!我之前在我的个人网站上做了一些类似的事情,写了一个 简短教程 :)
我喜欢生活流的想法,实际上我上个月用 雅虎!管道 和一些源,然后用一个 PHP 脚本解析所有内容来构建自己的 生活流。
我需要生成一些我使用的源,因此我将它们缓存到我自己的服务器上,这似乎缓解了一些源,特别是 Twitter 宕机的问题, Dave 正在回避。从 Twitter 构建一个缓存的源,并检查 Twitter 是否正常运行,然后生成一个更新的缓存,如果 Twitter 宕机,则从你自己的服务器获取先前生成的缓存,这将非常容易。
我很高兴看到这种趋势真正兴起!
@Jared: 非常棒,我喜欢它。可能需要注意使用 PHP/RSS 与使用实时 API 的优缺点。对于 RSS,许多网站会定期以平面文件形式生成它,甚至将其传递给像 Feedburner 这样的服务,最终托管 RSS。这意味着即使网站宕机,你的社交页面也可能保持完好无损。而如果你使用实时 API,你的页面则受该网站的支配。你可以通过进行一些自己的缓存来对抗它,但使用 jQuery/实时 API 的全部目的是它的使用非常简单 =)
@Jon: 也很酷。解析 RSS 和使用提供的 Twitter 小部件的组合。显然,不止一种方法可以达到目的 =)
@Terri: 没错,雅虎!管道是实现此目的的另一种方法。我相信还有更多方法。我们正处于这样一个时代,所有这些才华横溢的开发人员都在积极地思考如何帮助我们以尽可能简单的方式传播信息。网络的未来一片光明。
非常好的教程。一定要试一试!感谢分享。
不错的教程。感谢链接。
很棒的教程!谢谢!当我有一些空闲时间的时候,我一定要试试 ;-)
不错的教程,谢谢!
如果我的页面中有 Mootools,我不能使用它,对吧?!
很棒的教程,但是你亲自尝试过吗?
重点是,当你尝试使用 jQuery 动态获取数据时,你正在向 Twitter 发送一个 XMLHTTPRequest。Facebook 等等。这里的问题是,据我所知,Firefox(我认为其他浏览器也是这样)阻止你向除生成页面的服务器之外的服务器发送 XHR。
迟来的反应,你知道我上个月很忙,没有时间阅读你所有的帖子,但是像这种星期天下午,我有时间阅读它们,我真的很喜欢这篇文章。我仍然忙于学习 jQuery(最近也学习了一些 Mootools),这很有趣。谢谢!
不知道是不是只有我这样,但它似乎无法验证。所有错误都是对脚本的引用。
验证 URL
这里应该提到 Sweetcron,这是一项新的 **开源** “生活流” 服务,允许完全控制样式、源等。还可以托管在你的域上!
我可以用你上面写的内容制作自己的 Twitter 吗?
拜托……我打算制作自己的 Twitter
哇!越来越好了。继续努力,伙计。
还没有,有传言称 dA 将推出 API。但我最近没有看到任何相关信息。
我非常爱你!这里真是个好地方!
我可以将图片(Flickr)的大小更改为 75 x 75 的正方形格式吗?
这样有效吗?
嗨,克里斯,非常棒的教程。不知道你或其他人能否告诉我如何
a) 限制使用你上面提到的方法从 ScrnShots 获取的截图数量。
b) 如何只获取 ScrnShots 中标记为收藏夹的截图?
提前感谢你提供任何指点 :)