Google Code 有以下版本: English - Español - 日本語 - 한국어 - Português - Pусский - 中文(简体) - 中文(繁體)
该指南将帮助您构建 OpenSocial 应用程序。它是针对在一定程度上熟悉小工具 API 和 JavaScript 一般内容的开发人员设计的,但是如果您需要更多信息的话,里面也提供了其他资源的链接。
本文档进行了修改以反映 OpenSocial API 0.7 版更新所进行的更改。章节标记为新增!或更新来帮助您识别相对于上个版本而进行更改的编码实例。
社交应用程序就是在支持 OpenSocial JavaScript API 的容器上运行的应用程序。
要编写社交应用程序,您需要有:
OpenSocial API 主要针对用户。通过它,用户可以相互共享各自的活动并访问有关其好友的信息。在 OpenSocial API 中有三个主要功能区:
因为许多 API 调用需要服务器请求来检索或更新信息,所以它们是异步的。因此,您需要传送从服务器返回数据后执行的回调函数。
有关 OpenSocial JavaScript API 中的类和方法的详细信息,请参阅 API 参考。
要使用 OpenSocial API,请将以下 Requires 部分添加到您的应用程序中:
<ModulePrefs title="Title of Your Application"> <Require feature="opensocial-0.7"/> </ModulePrefs>
有关小工具 XML 规范的结构和内容的详细信息,请参阅《小工具 API 开发人员指南》。
我们先以列有好友名称的简单实例开始。但是首先,务必要先了解由 OpenSocial API 定义的角色:
本节中讨论的“列出好友”实例可以获取查看者和查看者的好友,并显示查看者好友的列表。介绍了如何获取并管理 OpenSocial 应用程序中的数据。基本步骤如下:
opensocial.newDataRequest() 创建 DataRequest。 DataRequest.add(request)。DataRequest 对象后,调用 DataRequest.send(callback)。DataResponse 参数。在“列出好友”中,DataResponse 包含查看者和查看者的好友。回调函数将会处理 DataResponse 中的数据。下面将详细讨论这些步骤。
要获取有关查看者和查看者好友的信息,请为要检索的每种数据类型创建新的 DataRequest 对象并向其添加请求。
/**
* Request for friend information when the page loads.
*/
function getData() {
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), 'viewer');
req.add(req.newFetchPeopleRequest(opensocial.DataRequest.Group.VIEWER_FRIENDS), 'viewerFriends');
req.send(onLoadFriends);
};
newFetch*Request() 调用中的最后一个参数是用于检索响应中的数据的字符串关键字。
假设您已在上一节做了实例练习。现在,您想要进行有关返回数据的练习,它的类型为 opensocial.DataResponse。以下 onLoadFriends() 回调函数将会解析用作参数的 DataResponse,并显示查看者和查看者好友的姓名:
/**
* Parses the response to the friend information request and generates
* html to list the friends by their display name.
*
* @param {Object} dataResponse Friend information that was requested.
*/
function onLoadFriends(dataResponse) {
var viewer = dataResponse.get('viewer').getData();
var html = 'Friends of ' + viewer.getDisplayName();
html += ':<br><ul>';
var viewerFriends = dataResponse.get('viewerFriends').getData();
viewerFriends.each(function(person) {
html += '<li>' + person.getDisplayName() + '</li>';
});
html += '</ul>';
document.getElementById('message').innerHTML = html;
};
使用传送到 newFetch*Request() 的字符串关键字调用 DataResponse.get(key) 会返回包括请求结果的 ResponseItem。
调用 dataResponse.get(key).getData() 会返回成功请求的实际响应数据。以下是与常规请求相关联的响应数据类型:
opensocial.Person 对象。 opensocial.Person 对象的 opensocial.Collection。如果指定请求不成功,则 DataResponse.get(key).hasError() 会返回 true。
本节会列出以上讨论的“列出好友”应用程序的完整代码。
在应用程序中,通常需要做的第一件事是请求您的应用程序所需的数据。请注意,代码包含该行:
gadgets.util.registerOnLoadHandler(getData);
这会将 getData() 注册为应用程序的装载处理程序,这意味着应用程序进行的第一件事是获取查看者和查看者好友数据(通过 getData())。
以下是完整实例。它会将其输出写入到 ID 为 "message" 的 <div> 中。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="List Friends Example">
<Require feature="opensocial-0.7"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<script type="text/javascript">
/**
* Request for friend information.
*/
function getData() {
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), 'viewer');
req.add(req.newFetchPeopleRequest(opensocial.DataRequest.Group.VIEWER_FRIENDS), 'viewerFriends');
req.send(onLoadFriends);
};
/**
* Parses the response to the friend information request and generates
* html to list the friends along with their display name.
*
* @param {Object} dataResponse Friend information that was requested.
*/
function onLoadFriends(dataResponse) {
var viewer = dataResponse.get('viewer').getData();
var html = 'Friends of ' + viewer.getDisplayName();
html += ':<br><ul>';
var viewerFriends = dataResponse.get('viewerFriends').getData();
viewerFriends.each(function(person) {
html += '<li>' + person.getDisplayName() + '</li>';
});
html += '</ul>';
document.getElementById('message').innerHTML = html;
};
gadgets.util.registerOnLoadHandler(getData);
</script>
<div id="message"> </div>
]]>
</Content>
</Module>
OpenSocial API 支持保存和检索每个用户和每个应用程序的数据。在 OpenSocial v0.5 和 v0.6 中也支持每个应用程序实例和全局应用程序数据,但是在 v0.7 中没有了。
该代码段显示了将数据保存到共享存储中的方式:
function populateMyAppData() {
var req = opensocial.newDataRequest();
var data1 = Math.random() * 5;
var data2 = Math.random() * 100;
var data3 = new Date().getTime();
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField1", data1));
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField2", data2));
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField3", data3));
req.send(handlePopulateMyAppData);
};
您可以按以下方式检索存储在以上代码段中的数据:
var req = opensocial.newDataRequest();
//Request the following three app fields
var fields = [ "AppField1", "AppField2", "AppField3" ];
req.add(req.newFetchPersonAppDataRequest("VIEWER", fields), "viewer_data");
req.send(handleRequestMyData);
以下是应用程序的完整代码。它将为查看者设置一些值,然后对其进行检索:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Data Persistence Example" >
<Require feature="opensocial-0.7"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<script type="text/javascript">
gadgets.util.registerOnLoadHandler(populateMyAppData);
var htmlout = "";
var me = null;
/************************************************************************
* Set user data
*/
function populateMyAppData() {
var req = opensocial.newDataRequest();
var data1 = Math.random() * 5;
var data2 = Math.random() * 100;
var data3 = new Date().getTime();
htmlout += "Setting AppField1 to " + data1 + "<br />";
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField1", data1)) + "<br />";
htmlout += "Setting AppField2 to " + data2 + "<br />";
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField2", data2)) + "<br />";
htmlout += "Setting AppField3 to " + data3 + "<br />";
req.add(req.newUpdatePersonAppDataRequest("VIEWER", "AppField3", data3)) + "<br />";
req.send(handlePopulateMyAppData, "update_appdata");
}
/************************************************************************
* Handle responses from update person app data requests
*/
function handlePopulateMyAppData(data) {
if (data.hadError()) {
htmlout += data.getError();
}
requestMyData();
}
/************************************************************************
* Fetch app data
*/
function requestMyData() {
var req = opensocial.newDataRequest();
var fields = [ "AppField1", "AppField2", "AppField3" ];
req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), "viewer");
req.add(req.newFetchPersonAppDataRequest("VIEWER", fields), "viewer_data");
req.send(handleRequestMyData);
}
/************************************************************************
* Handle responses from app data requests
*/
function handleRequestMyData(data) {
var mydata = data.get("viewer_data");
var viewer = data.get("viewer");
me = viewer.getData();
if (mydata.hadError()) {
htmlout += data.getError();
return;
}
// Do something with the returned data - note the getData call
doSomethingWithMyData(mydata.getData());
}
/************************************************************************
* Operate on user data
*/
function doSomethingWithMyData(data) {
//Data is indexed by user id, and represents an object where keys
//correspond with the app data fields.
var mydata = data[me.getId()];
var div = document.getElementById('content_div');
htmlout += "My AppField1 data is: " + mydata["AppField1"] + "<br />";
htmlout += "My AppField2 data is: " + mydata["AppField2"] + "<br />";
htmlout += "My AppField3 data is: " + mydata["AppField3"] + "<br />";
div.innerHTML = htmlout;
}
</script>
<div id="content_div"></div>
]]>
</Content>
</Module>
注意:存储在 OpenSocial 应用程序中的数据始终是字符串。在大多数用途中,使其成为 JSON 编码字符串比较实用。因为 OpenSocial 执行自动 HTML(对所有包括应用程序数据的返回数据进行编码),所以必须在解析它们之前对应用程序数据存储中字符串化的 JSON 对象进行解码。例如:
var unescapedString = gadgets.util.unescapeString(jsondata); var obj = gadgets.json.parse(unescapedString);
OpenSocial API 可让您通过活动流与好友共享活动。活动流是一种供稿,其中的每个条目都表示用户执行的操作。活动可以是任何形式(从修改应用程序状态到编写电影的在线评论)。
如果请求高活动优先级,则当应用程序没有有许可时,应用程序会要求用户提供其代表用户发布活动的许可。如果请求低优先级,则当应用程序没有发布许可时,该调用无效。
该简单的实例说明了如何创建活动:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Activities - v0.7" >
<Require feature="opensocial-0.7"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<div id="content_div"></div>
<script type="text/javascript">
var div = document.getElementById('content_div');
function postActivity(text) {
var params = {};
params[opensocial.Activity.Field.TITLE] = text;
var activity = opensocial.newActivity(params);
opensocial.requestCreateActivity(activity, opensocial.CreateActivityPriority.HIGH, callback);
div.innerHTML = "Activity title is: " + activity.getField(opensocial.Activity.Field.TITLE);
};
// The parameter passed to the callback is an opensocial.ResponseItem that
// indicates whether the activity creation request succeeded.
function callback(status) {
if (status.hadError())
{
alert("Error creating activity.");
}
else
{
alert("Activity successfully created.");
}
};
postActivity("This is a sample activity, created at " + new Date().toString());
</script>
]]>
</Content>
</Module>
OpenSocial API 使应用程序可以通过以下方式与其容器交互:
您可以使用 gadgets.views.requestNavigateTo 将应用程序从容器的一个页面带到另一个页面(例如,将个人资料页面链接到画布页面)。
该实例显示了如何使用 API 从一个视图浏览到另一个视图。它显示了链接列表,用户可以单击这些链接以浏览至容器的可用视图。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Navigating Between Views (0.7)" description="Navigates between views">
<Require feature="opensocial-0.7" />
<Require feature="views" />
</ModulePrefs>
<Content type="html">
<![CDATA[
<div id="main"></div>
<script type="text/javascript">
/**
* Create the list of links to the other views
*/
function createLinks() {
//Get the environment, current view and an object containing the supported views
var env = opensocial.getEnvironment();
var views = gadgets.views.getSupportedViews();
var currentview = gadgets.views.getCurrentView();
var text = [ "You are currently on the ",
currentview.getName(),
" view. Other views: " ].join("");
//Set up some DOM
var outputdom = document.getElementById("main");
outputdom.appendChild(document.createTextNode(text));
var ol = document.createElement("ol");
outputdom.appendChild(ol);
//Iterate over each view
for (var viewname in views) {
var view = views[viewname];
// Make some DOM to present each link
var li = document.createElement("li");
var a = document.createElement("a");
ol.appendChild(li);
li.appendChild(a);
a.href = "javascript:void(0);";
//Put the name of the view in the link
a.appendChild(document.createTextNode("Link to " + view.getName()));
//Handle when the user clicks a link to the other server
a.onclick = getNavigateClosure(view);
}
};
/**
* Returns a function that navigates to the supplied view
*/
function getNavigateClosure(view) {
return function() { gadgets.views.requestNavigateTo(view); };
};
//Execute createLinks when the page is done loading
gadgets.util.registerOnLoadHandler(createLinks);
</script>
]]>
</Content>
</Module>
请注意以上实例中的该功能:
function getNavigateClosure(view) {
return function() { gadgets.views.requestNavigateTo(view); };
};
它会使用称为闭包的技术。在该上下文中,这意味着从其他函数内调用的函数可以访问外层函数的本地变量。当用户单击选中视图的链接时,在此使用闭包可以将选中视图的名称传送到 requestNavigateTo() 方法。
Environment 类包含 getDomain 方法,您可以通过此方法了解您所在的站点(例如 orkut.com 或 myspace.com)。这使您的应用程序可以对不同的环境以不同的方式响应。当 API 仅返回相对网址时,getDomain 方法可以帮助构建绝对网址。但是,通常情况下,我们建议您对所有函数改用另一种方法 hasCapability,。hasCapability 方法会获取函数名称并告知您该函数在当前容器中是否可用。这可让容器将自身的扩展名添加到 OpenSocial,同时还为开发人员提供了一个通用机制来对其进行访问。该容器特定的扩展也会显示在 supportsField 方法中。容器提供者可添加自己的人物或活动字段。要符合 OpenSocial 规范,需要在 opensocial 名称空间外的某处记录该字段。
该实例应用程序根据用户是在个人资料页面中还是在画布页面中来更改其显示。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="My 0.7 Environment">
<Require feature="opensocial-0.7"/>
</ModulePrefs> <Content type="html">
<![CDATA[
<script type="text/javascript">
/**
* Request for friend information when the page loads.
*/
function getData() {
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), 'viewer');
req.send(greetUser);
}
/**
* Change the display of the user greeting depending on whether the
* user is in the profile or the canvas.
*/
function greetUser(dataResponse) {
var viewer = dataResponse.get('viewer').getData();
// Determine whether the getCurrentView feature is supported
var isAble = gadgets.util.hasFeature("gadgets.views.getCurrentView");
var html = '<h2>Greetings, ' + viewer.getDisplayName() + '!</h2>';
// If the container supports the getEnvironment method, determine whether the user
// is in the canvas or profile
if (isAble)
{
var currView = gadgets.views.getCurrentView();
// If the user is in the canvas, display the canvas view of the greeting
if (currView.getName() == 'canvas')
{
showCanvasView(html);
}
// Otherwise, display the profile view of the greeting
else
{
// If the container supports the field THUMBNAIL_URL for PERSON objects,
// include it in the profile view greeting page
var myenv = opensocial.getEnvironment();
if (myenv.supportsField(opensocial.Environment.ObjectType.PERSON, opensocial.Person.Field.THUMBNAIL_URL))
{
var thumb = viewer.getField(opensocial.Person.Field.THUMBNAIL_URL);
html += "<img src=" + thumb + "/>";
}
// Display the greeting in the profile and include the user's thumbnail
document.getElementById('profile-div').innerHTML = html;
}
}
// Default: just display the greeting with no image
else {
document.getElementById('profile-div').innerHTML = html;
}
}
/** If the user is in canvas, change the display to take advantage of
* additional screen area
*/
function showCanvasView(str) {
var div = document.getElementById('canvas-div');
div.style.display="";
str += "<img src='http://gadget-doc-examples.googlecode.com/svn/trunk/my-canvas-photo.jpg' />";
div.innerHTML = str;
}
gadgets.util.registerOnLoadHandler(getData);
</script>
<div id="profile-div"> </div>
<div id="canvas-div" style="display:none; font-family:Tahoma; background-color: #FFC0CB; margin: 5px; height: 570px; text-align: center;"></div>
]]>
</Content>
</Module>
在小工具 XML 文件中可以包含多个 <Content> 部分,其中每个 <Content> 部分都会公布它要呈现在上面的视图。文档树中所有 <Content> 部分都应该是同一类,并使用可选参数 view= 定义应在其中呈现的视图。
以下简单实例显示了具有两个内容部分的小工具:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Multiple Content Sections (version 1)">
<Require feature="opensocial-0.7" />
</ModulePrefs>
<Content type="html" view="profile">
<![CDATA[
<h1>Profile</h1>
]]>
</Content>
<Content type="html" view="canvas">
<![CDATA[
<h1>Canvas</h1>
]]>
</Content>
</Module>
输出如下:
个人资料视图
<h1>Profile</h1>
画布视图
<h1>Canvas</h1>
画布或个人资料以外的其他任何视图
不显示任何内容
内容部分可指定多个视图,由逗号隔开:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Multiple Content Sections (version 2)">
<Require feature="opensocial-0.7" />
</ModulePrefs>
<Content type="html" view="canvas,profile">
<![CDATA[
<h1>Canvas and Profile</h1>
]]>
</Content>
</Module>
输出如下:
个人资料视图
<h1>Canvas and Profile</h1>
画布视图
<h1>Canvas and Profile</h1>
画布或个人资料以外的其他任何视图
不显示任何内容
如果指定具有视图参数的内容部分,则该内容部分仅会显示在该视图上。如果未指定默认内容部分,则其他视图将不会显示任何内容。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Multiple Content Sections (version 3)">
<Require feature="opensocial-0.7" />
</ModulePrefs>
<Content type="html" view="profile">
<![CDATA[
<h1>Profile</h1>
]]>
</Content>
</Module>
输出如下:
个人资料视图
<h1>Profile</h1>
画布视图
不显示任何内容
画布或个人资料以外的其他任何视图
不显示任何内容
要指定默认内容部分,只需定义没有视图参数的内容部分即可:
<Module>
<ModulePrefs title="Multiple Content Sections (version 4)">
<Require feature="opensocial-0.7" />
</ModulePrefs>
<Content type="html" view="profile">
<![CDATA[
<h1>Profile</h1>
]]>
</Content>
<Content type="html">
<![CDATA[
<h1>Default</1>
]]>
</Content>
</Module>
输出如下:
个人资料视图
<h1>Profile</h1>
画布视图
<h1>Default</h1>
画布或个人资料以外的其他任何视图
<h1>Default</h1>
您可以在一个小工具中使用所有这些技术:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Multiple Content Sections (version 5)">
<Require feature="opensocial-0.7" />
</ModulePrefs>
<Content type="html" view="profile">
<![CDATA[
<h1>Profile</h1>
]]>
</Content>
<Content type="html" view="canvas">
<![CDATA[
<h1>Canvas</h1>
]]>
</Content>
<Content type="html" view="canvas,profile">
<![CDATA[
<h2>This shows up in canvas and profile views</h2>
]]>
</Content>
<Content type="html">
<![CDATA[
<h1>Default</h1>
<h2>The content in this section only shows up if no other content sections are applicable</h2>
]]>
</Content>
</Module>
输出如下:
个人资料视图
<h1>Profile</h1>
<h2>This shows up in canvas and profile views</h2>
画布视图
<h1>Canvas</h1>
<h2>This shows up in canvas and profile views</h2>
画布或个人资料以外的其他任何视图
<h1>Default</h1>
<h2>The content in this section only shows up if no other content sections are applicable</h2>
您可以使用 gadgets.io.makeRequest() 方法远程获取其他网络服务器和网页的内容。在对旧的小工具 API IG_Fetch... 方法的改进中,gadgets.io.makeRequest() 考虑了 POST 和 GET,您可以指定是否要注册您的请求甚至是进行验证。
gadgets.io.makeRequest() 方法会采用这些参数:
默认情况下,makeRequest() 会使用 GET 方法获取数据,并且内容的默认类型为 TEXT(其中网页的内容作为原始文本获取)。
该实例显示了 API 的简单使用方法。它会获取 www.google.com 上的前 400 个字符,并将它们输出到 <div>:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Fetch Content as Text">
<Require feature="opensocial-0.7"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<div id="content_div"></div>
<script type="text/javascript">
function makeNormalRequest() {
var params = {};
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.TEXT;
var url = "http://www.google.com";
gadgets.io.makeRequest(url, response, params);
};
function response(obj) {
//obj.text contains the text of the page that was requested
var str = obj.text;
var html = str.substr(0,400);
document.getElementById('content_div').innerHTML = html;
};
makeNormalRequest();
</script>
]]>
</Content>
</Module>
默认情况下,对 makeRequest 的调用将会进行缓存。在以下实例中,包装函数会采用与 makeRequest 调用相同的参数,但是会接受名为 refreshInterval 的其他参数,您可以通过该参数指定缓存持续时间。但是,缓存很有用,您应注意不要过于频繁地刷新缓存而导致性能降低。缓存可让您更快地获取数据。它也降低了托管远程内容的第三方服务器上的负载。您应当尝试避免完全禁用缓存(通过将其指定为 0 来禁用)。有关该主题的更多讨论内容,请参阅《小工具 API 开发人员指南》。
function makeCachedRequest(url, callback, params, refreshInterval) {
var ts = new Date().getTime();
var sep = "?";
if (refreshInterval && refreshInterval > 0) {
ts = Math.floor(ts / (refreshInterval * 1000));
}
if (url.indexOf("?") > -1) {
sep = "&";
}
url = [ url, sep, "nocache=", ts ].join("");
gadgets.io.makeRequest(url, response, params);
}
该实例显示了使用 DOM 内容类型处理 XML 数据的方式。当指定 DOM 内容类型后,makeRequest() 将作为 DOM 对象检索指定的 XML 文档。拥有该对象后,您可以使用标准 DOM JavaScript 函数对其进行操作。有关该主题的更多讨论内容,请参阅《小工具 API 开发人员指南》。
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Fetch XML">
<Require feature="opensocial-0.7"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<div id="content_div"></div>
<script type="text/javascript">
function makeDOMRequest() {
var params = {};
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.DOM;
var url = "http://doc.examples.googlepages.com/breakfast-data.xml";
gadgets.io.makeRequest(url, response, params);
};
function response(obj) {
// obj.data contains a Document DOM element corresponding to the
// page that was requested
var domdata = obj.data;
var title = domdata.getElementsByTagName("menu").item(0).getAttribute("title");
var html = "<h2>" + title + "</h2>";
// Get a list of the <food> element nodes in the file
var itemList = domdata.getElementsByTagName("food");
// Loop through all <food> nodes
for (var i = 0; i < itemList.length ; i++) {
// For each <food> node, get child nodes.
var nodeList = itemList.item(i).childNodes;
// Loop through child nodes. Extract data from the text nodes that are
// the children of the associated name, price, and calories element nodes.
for (var j = 0; j < nodeList.length ; j++) {
var node = nodeList.item(j);
if (node.nodeName == "name") {
var name = node.firstChild.nodeValue;
}
if (node.nodeName == "price") {
var price = node.firstChild.nodeValue;
}
}
html += name + " - ";
html += price + "<br />";
}
html += "</div>";
document.getElementById('content_div').innerHTML = html;
};
makeDOMRequest();
</script>
]]>
</Content>
</Module>
您可以使用 JSON 内容类型作为 JavaScript 对象获取 JSON 编码的内容。
以下应用程序将从包含以下 JSON 编码的字符串的示例 PHP 页面中获取内容:
{"validated":"This request was spoofed","query":[],"url":"http:\/\/graargh.returnstrue.com\/buh\/fetchme.php","signature":"","signature_len":1}
从包含该字符串的 PHP 页面获取内容后,返回值是包含关键字值对(即,关联数组)的 JavaScript 对象。该示例会检索对象,然后打印出它所包含的关键字值对:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="Fetch JSON 8">
<Require feature="opensocial-0.7"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<div id="content_div"></div>
<script type="text/javascript">
function makeJSONRequest() {
var params = {};
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
// This URL returns a JSON-encoded string that represents a JavaScript object
var url = "http://graargh.returnstrue.com/buh/fetchme.php";
gadgets.io.makeRequest(url, response, params);
};
function response(obj) {
var jsondata = obj.data;
var html = "<strong>Values: </strong><br /><br />";
// Returned JS object can be processed as an associative array
for (var key in jsondata) {
var item = jsondata[key];
html += key + ": ";
html += item + "<br />";
}
document.getElementById('content_div').innerHTML = html;
};
makeJSONRequest();
</script>
]]>
</Content>
</Module>
JSON(JavaScript 对象表示法)是数据交换格式,使您可以将某些对象类型(关键字值对的数组和集合)作为可以轻松传送的字符串进行编码。
小工具 API 提供了 gadgets.json.stringify() 方法用于将对象编码为 JSON 字符串,并提供 gadgets.json.parse() 方法用于将 JSON 字符串返回到对象。请注意,因为 OpenSocial 执行自动 HTML(对所有包括应用程序数据的返回数据进行编码),所以必须在解析它们之前对应用程序数据存储中字符串化的 JSON 对象进行解码,例如:gadgets.util.unescapeString(jsondata)。
该实例创建了 JavaScript 数组,并将其编码为 JSON 字符串,然后将 JSON 字符串转换回数组对象:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="JSON Example">
<Require feature="opensocial-0.7"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<div id="content_div"></div>
<script type="text/javascript">
var html = "";
// Create Array object
var myfriends = new Array();
myfriends[0] = "Touki";
myfriends[1] = "Rowan";
myfriends[2] = "Trevor";
// Encode array as JSON string
var jsonString = toJSON(myfriends);
html += "The JSON string is " + jsonString + "<br />";
html += "The type of jsonString is " + typeof(jsonString) + "<br />";
// Convert JSON string back to an object
var arr_obj = toObject(jsonString);
html += "The type of arr_obj is " + typeof(arr_obj);
document.getElementById('content_div').innerHTML = html;
// Encode object as JSON string
function toJSON(obj) {
return gadgets.json.stringify(obj);
}
// Convert JSON string into an object
function toObject(str) {
return gadgets.json.parse(str);
}
</script>
]]>
</Content>
</Module>
该小工具的输出如下:
The JSON string is ["Touki","Rowan","Trevor"] The type of jsonString is string The type of arr_obj is object
默认情况下,使用 GET 方法获取远程内容。您可以通过 POST_DATA 参数以改用 POST 方法来获取内容。例如:
function makePOSTRequest() {
var params = {};
var postdata = {
data1 : "test",
data2 : 1234566
};
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
params[gadgets.io.RequestParameters.POST_DATA] = gadgets.io.encodeValues(postdata);
var url = "http://graargh.returnstrue.com/buh/makerequest.php";
gadgets.io.makeRequest(url, response, params);
};
function response(obj) {
// do something
};
makePOSTRequest();
小工具 API 支持以下授权类型:
gadgets.io.AuthorizationType.AUTHENTICATED(容器使用完全验证) gadgets.io.AuthorizationType.SIGNED(由容器注册请求) gadgets.io.AuthorizationType.NONE(默认值) 如何使用这些方式取决于您的容器。以下是使用专用于 Orkut 的注册授权类型的一个实例
OpenSocial API 支持应用程序中的许可控制。当应用程序使用数据请求从服务器获取查看者时,则只会在应用程序具有访问权限时返回。如果应用程序没有访问权限,则会返回其中一个标准错误代码 opensocial.ResponseItem.Error.UNAUTHORIZED。应用程序还可以通过使用新 opensocial.hasPermission 调用提前检查其访问权限。如果访问被拒绝,则可以使用 opensocial.requestPermission 向查看者要求指定的许可。当然,某些容器可能始终授予查看者访问权限,而某些则可能始终拒绝,但是该决定取决于容器。
该摘录说明了使用许可控制 API 的方式:
/**
* Request the VIEWER and OWNER objects
*/
function requestData() {
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.OWNER), "owner");
// If we have permission to see the viewer's info, then add it to the request.
if (opensocial.hasPermission(opensocial.Permission.VIEWER)) {
req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), "viewer");
}
req.send(showData);
}
function showData(data) {
var viewer = data.get("viewer").getData();
var owner = data.get("owner").getData();
var ownerOutput = document.getElementById("owner-output");
var viewerOutput = document.getElementById("viewer-output");
showPerson(owner, ownerOutput);
if (opensocial.hasPermission(opensocial.Permission.VIEWER)) {
showPerson(viewer, viewerOutput);
}
}
function requestPermission() {
var reason = "To demonstrate permission capabilities";
opensocial.requestPermission(opensocial.Permission.VIEWER, reason, requestData);
}
function showPerson(person, div) {
var name = person.getDisplayName();
var thumb = person.getField(opensocial.Person.Field.THUMBNAIL_URL);
var html = '<img src="' + thumb + '"/>' + name;
div.innerHTML = html;
}
//Execute requestData when the page is done loading
gadgets.util.registerOnLoadHandler(requestData);
要了解有关 OpenSocial API 的更多内容,以下是一些附加资源:
| 修订 | 更新 | 说明 |
|---|---|---|
| OpenSocial 0.8.1 | 2008 年 9 月 | 大部分章节均已更新。Require 语句已更改为 0.8。访问示例现在使用 IdSpec。已添加了有关清除持久化数据的信息。已更新了权限示例。 |
| OpenSocial 0.7 | 2008 年 4 月 | 新文档。 |