Developing Facebook applications with ColdFusion
社交网络的崛起是 Internet 世界中引人注目的成果之一,也是我们普遍热衷和常用的。MySpace 是这一阵营中的典范(有时令人感觉不舒服),但它绝不是唯一的社交网络。Facebook 的受欢迎程度可能仅次于 MySpace,并且在声誉方面略显成熟,但也不是从头到尾一本正经的。但是 Facebook 却以不同于其他社交网络的方式进行了创新。
2004 年 5 月,Facebook 推出了一个全新的 API(称为 Facebook 平台),它令整个社交网络面目一新。现在,您只要遵循特定 API 即可编写出自己的应用程序,基本上是以 Facebook 创建的网络为构建基础并进行扩展。这一 API 支持以任何服务器端语言编写的应用程序,但既然有最好的现成语言 ColdFusion,为什么要使用其他语言呢?本文说明如何创建一个简单的、基于 ColdFusion 的 Facebook 应用程序。
要求
为了充分利用本文,您需要以下软件和文件:
ColdFusion 8必备知识
熟悉 ColdFusion。
您在使用 Facebook 方面必须了解的第一件事是它不同于您过去使用的其他 API,这可能也是最重要的一点。让我们看看 Yahoo! API(您可以在 找到针对这个 API 的不错的 ColdFusion 打包程序)。Yahoo! API 是一套 URL,服务器端代码可以使用它们请求一组特定数据,然后对响应进行语法分析。因此,要了解洛杉矶 Lafayette 的天气,我只需要让 ColdFusion 请求以下 URL: http://weather.yahooapis.com/forecastrss?p=70508。这将返回一个 RSS 响应,使用 ColdFusion 对它进行语法分析易如反掌。但是,请注意这里的执行顺序。用户访问我的站点并请求特定 ColdFusion 文件。我的 ColdFusion 代码在幕后对 Yahoo 执行 HTTP 调用并对响应进行语法分析。经过语法分析后的响应随后返回给用户。
Facebook 改变了这种情况。由于您需要扩展 Facebook 站点,而不是您自己的站点,所以您构建的代码与 Yahoo 服务十分类似。用户将访问 Facebook 站点并运行您的应用程序。Facebook 就像是一个经纪人。它代表用户向您的服务器发送 HTTP 请求。您的服务器将检查调用并做出响应。Facebook 随后将结果返回给用户。
当您的代码对 Facebook 做出响应时,它可以包含普通的 HTML(受到一些限制)和 FBML(Facebook 标记语言)。FBML 包含一些特殊标签,Facebook 首先会对它们进行语法分析,然后返回给用户。FBML 包含一些基本的构件和布局支持以及可以自动载入用户数据的项目。以下是一个简单的示例。(您现在还不必担心实际的语法,我只是通过这个示例向您展示 FBML 的外观。)
<fb:dashboard> <fb:create-button href="#">Hello world!</fb:create-button></fb:dashboard>
这将在我的 Facebook 页面中创建一个简单的按钮(请参阅图 1)。
图 1:Facebook 中一个简单的 Hello World 按钮
请注意,这个按钮采用了正确的样式,与站点中的其他内容保持风格一致。以下是另一个示例,您同样不必担心代码,但必须注意结果:
<cfoutput><p> Hello <fb:name uid="#request.userID#" useyou="false"/>!</p>Here are your friends: <fb:friend-selector uid="#request.userID#"name="uid" idname="friend_sel" /></cfoutput>
在这个示例中,我将使用 fb:name 标签,它显示了用户的姓名。第二个标签 fb:friend-selector 将创建一个漂亮的、基于 Ajax 的朋友选择器。当我键入内容时,这个选择器会显示一个与我的搜索内容匹配的姓名列表(请参阅图 2)。
图 2:使用 name 和 friend-selector 标签的范例 Facebook 页面
这个平台的另一个部分是 REST 接口。FBML 允许您轻松包含 UI 项目和构件,还能帮助您请求其他信息。例如,REST 接口允许您的应用程序向用户发送通知。它允许应用程序与事件进行交互。它甚至允许应用程序与您的朋友进行交互。有关令这个 REST 接口简单易用的 ColdFusion 组件的相关信息,请参阅“后续工作”部分。
这个平台的另一个功能是 FQL,又称 Facebook 查询语言。您可能猜的到,这是 Facebook 的一个 SQL 型接口。以下是一个简单的示例:
select name, picfrom user where uid IN (SELECT uid2 FROM friend WHERE uid1 = X)and sex = 'Female'
这段代码将从女性 ×(这通常是一个 Facebook 用户 ID)的所有朋友中选择某个姓名和照片。您可以通过 REST API 使用 FQL 对 Facebook 执行更复杂的交互。这个平台的功能远不止这些,但我们先使用 ColdFusion 从一个简单的应用程序入手。
Facebook 必不可少的“Hello World”
您首先必须成为 Facebook 网络的成员,才能使用 Facebook 平台进行任何操作。这是显而易见的,但如果您感到好奇,就必须拥有一个有效帐户才能着手操作。完成注册或登录后,请访问 站点。您应当为这个站点添加书签,因为它将成为您的示例、文档和支持门户。接下来的部分十分精彩。要为 Facebook 创建应用程序,您将使用一个 Facebook 应用程序。(我喜欢递归!)当您访问 时,您会看到这个 Developer 应用程序。将提示您是否允许 Developer 应用程序访问您的信息。您必须同意,才能继续。安装后,这个应用程序是您创建自己的应用程序的主要工具集。单击这个漂亮、显眼的“Set Up New Application”按钮,即可看到图 3 中显示的表单。
图 3:“New Application”表单
在这个示例中,我将它命名为“HelloWorld”,也可以使用其他名称。现在还不必担心可选字段。选中复选框,同意 Facebook 平台条款(当然,请仔细阅读这些条款),然后单击“Submit”。现在,您将看到基本帐户页面,如图 4 所示。
图 4:Facebook 显示新启动的 HelloWorld 应用程序。
应用程序此时已经创建完毕,您需要编辑一些设置,才能开始处理等式的 ColdFusion 部分。(Facebook 包含范例代码,但对于 ColdFusion 开发人员而言很可惜,因为它是用 PHP 语言编写的。)单击“Edit Settings”。您必须考虑到两个重要设置。第一个是 Callback URL。这是服务器上的 URL,当运行您的应用程序时,Facebook 将与它通信。它不可以是您的 localhost 上的某个文件。它必须在整个 Internet 都可以使用的某台“实际”Web 服务器上。我测试时使用了:。
请注意,我并没有包含文件名。Callback URL 就像是应用程序的根目录。这允许 Facebook 请求其他文件,如 foo.cfm,并将请求代理到服务器上的同一文件。例如,您的应用程序的 Facebook 托管版发出的 foo.cfm 请求实际将转到 http://www.coldfusionjedi.com/demos/sep09helloworld/foo.cfm。
第二个重要设置是 Canvas Page URL。这是您的应用程序在整个 Facebook 中的特定 URL。当您键入值时,网页将用 AJAX 发出调用并确定该值是否可用。我发现它有点古怪,并且无法始终返回正确的消息。正如您可能猜到的,HelloWorld 已经被占用,所以我使用了 sephelloworld。这意味着人们转到 就可以访问我的应用程序。
保存您所做的更改。现在,您可以尝试通过以下网址查看您的应用程序: http://apps.facebook.com/<your-application-name>/。您很可能看到默认的 Facebook 错误屏幕(它很常见,不必惊慌!)。
注意:如果您尝试添加我在本文中创建的应用程序,您肯定不会收到错误,因为我已经将这个应用程序放到服务器端。
图 5:HTTP 错误表明尚未设置 Hello World 应用程序
当我尝试查看 时,收到 404 错误并没有令我吃惊,因为我还没有创建文件夹(请参阅图 5)。回到我的服务器后,我创建了这个文件夹并添加了包含“Hello World!”的 index.cfm 文件。当我重新载入时,立即收到了一条 500 错误。现在又怎么了?如果使用 ColdFusion Administrator 查看错误,您可能会看到以下内容:
Form entries are incomplete or invalid.<ul><li>1221770931.3016</li></ul> Go <a href=""javascript:history.back()"">back</a> andcorrect the problem. The specific sequence of files included orprocessed is: D:\mypathissecret\demos\sep09helloworld\index.cfm''
那么,它又意味着什么呢?原来,这是 ColdFusion 中的一个旧功能的副作用。
几年前,Allaire 添加了一个功能,旨在允许自动表单验证。您只需将表单字段以特定方式命名,ColdFusion 就可以执行自动服务器端验证。使用这个功能的人并不多,但不幸的是,没有办法关闭它,所以这个话题时常会冒出来!此时,使用 ColdFusion 开发 Facebook 应用程序会遇到一个大问题。Facebook 执行 POST 操作,这些操作使用某个表单字段。ColdFusion 不允许您禁用检查,而您又无法告诉 Facebook 更改它们的 API(您当然可以试试,不过我只能祝你好运)。解决方法是重命名表单字段,确保 ColdFusion 不会尝试验证它们。要做到这点,您可以重新编写 Application.cfc 级别的数据进入形式。有关更多信息,请参阅。
以下是我用于实施这一修正的 Application.cfc 文件:
<cfcomponent output="false"><cfset this.name = "sep09helloworld"><cfif structKeyExists(form, "FB_SIG")><cfset form.FB_SIG_FIX = form.FB_SIG><cfset form.FB_SIG = ''></cfif></cfcomponent>
这是一个很小的 Application.cfc 文件。通常我会在其中包含更多方法,但我在这里只希望与您分享可以修复 POST 问题的最精简的修正方法。请注意,它基本上就是找出导致问题的表单值 (FB_SIG)、复制它,然后删除旧值。保存后,您基本上可以忘记这个文件,只需记住要将引用 FB_SIG 的任何 Facebook 文档引用为 FB_SIG_FIX。如果正确完成所有操作,当您在浏览器中重新载入应用程序时,应该可以看到图 6 所示的 Hello World 消息。
图 6:Facebook 中的简单 Hello World! 应用程序。
此时,您在 Facebook 和您的服务器之间建立了连接。现在即可使用 FBML 和 API 增强您的应用程序。我们可以把 index.cfm 变得更有趣些:
<cfoutput><fb:tabs><fb:tab-item href="index.cfm" title="Home" selected="true"/><fb:tab-item href="about.cfm" title="About"/></fb:tabs><h3>Hello world</h3><p>The time is #timeFormat(now(), "short")#</p></cfoutput>
我在这里使用了一些 FBML,这样可以添加一些基本导航功能。您可能已经猜到,这会创建出简单的、基于选项卡的导航机制。请注意,我使用的是简单的相对 URL。由于 Facebook 使用起来就像代理一样,我只需给出一些地址,它们将清理我之前设置的根回调 URL。我添加了一些 ColdFusion 代码和一个时间显示,它们可以确保一切运转正常。然后在浏览器中重新载入应用程序(请参阅图 7)。
图 7:应用程序现在包含选项卡和当前时间
随后,我在名为 about.cfm 的服务器上添加一个新文件。因为只要测试导航功能,所以我使用了以下代码:
<cfoutput>
<fb:tabs>
<fb:tab-item href="index.cfm"
title="Home"/>
<fb:tab-item href="about.cfm"
title="About" selected="true"/>
</fb:tabs>
<h3>About</h3>
<p>
Thanks for visiting the about page.
</p>
</cfoutput>
请注意,我重复了选项卡,但这次将 About 页面设置为选定值。这样的代码可以轻松提取到 ColdFusion 自定义标签中,从而可以更简单地为您的 Facebook 应用程序提供布局。
处理 Facebook POST 的另一种方法
Jason Delmore 与我们分享了处理本文先前部分中讨论的 POST 操作问题的另一种有趣而出色的方法。他的代码可以处理任何及所有可能的表单字段,它们可能会意外触发 ColdFusion 的自动服务器端验证。我之前并未提供他的代码,因为我希望首先介绍一种快速、简单的解决方法。Jason 的解决方法虽然更复杂,在处理这个问题方面却更出色。以下是他的 Application.cfc 模板:
<cfcomponent output="yes">
<cfset this.name = "sep09helloworld">
<cfset url.form = structnew()/>
<cfset structappend(url.form,form)/>
<cfset structclear(form)/>
<cffunction name="onRequestStart">
<cfset structappend(form,url.form)/>
<cfset structdelete(url,"form")/>
</cffunction>
</cfcomponent>
请注意文件的“constructor”部分(这个部分用于每个请求)中的以下三行内容:
<cfset url.form = structnew()/>
<cfset structappend(url.form,form)/>
<cfset structclear(form)/>
这段代码在名为 form 的 URL 范围中创建一个新密钥。他将整个表单范围附加(即复制)到 URL 结构,然后清除整个表单。我们现在来看看 onRequestStart 方法:
<cfset structappend(form,url.form)/>
<cfset structdelete(url,"form")/>
这两行代码将数据从 URL 范围复制回表单范围,然后从 URL 结构中删除该密钥。这似乎毫无意义。代码只是将数据从一个结构复制到另一个,然后再复制回来。但是,这个临时的数据“转移”足以跳过 ColdFusion 的服务器端验证。
后续工作
显然,我只提到了可以通过 Facebook 平台实现的一小部分;我希望重点讨论 ColdFusion 集成。建议您仔细阅读 Facebook 开发人员文档*。它对于构建应用程序会有所帮助。您还可以了解一下应用程序的不同选项。您可以根据事件(如用户删除您的应用程序)执行操作,也可以获取十分详细的报告。所有这一切都有助于改进您的应用程序,使它更受欢迎。(现在,您可以开始考虑用应用程序赚钱了!)
一些开发人员与我们慷慨分享自己的 ColdFusion 代码,帮助新的开发人员构建 Facebook 应用程序。建议您访问 RIAForge* 并搜索 Facebook。我借用了 Dominic Wilson 的 Facebook FBML Starter Kit*。它提供了一个很不错的入门模板,并且包含一个令基于 REST 的 API 更简单易用的 CFC。
评论:
1 条评论