<?xml version="1.0" encoding="utf-8"?>
<html>
<div style="float:right; margin: 0 0 10px 10px;">Version|opensocial-0.9
Table of Contents | ||||||||
---|---|---|---|---|---|---|---|---|
|
</div>
Sometimes OpenSocial gadgets need to work with data located on remote servers, but cannot make AJAX requests due to cross-browser limitations. Fortunately, the OpenSocial APIs provide functions to send HTTP requests to remote servers.
Your OpenSocial applications are able to:
...
- Securely transmit unique identifiers for the owner and viewer using*request signing*.
- Make HTTP requests from a gadget to a remote server using*osapi.http*.
- Request social information to be sent from the container to a server using*Data Pipelining*.
- Render a web page from a server as a gadget view using*Proxied Content*.
Request Signing
When sending data from a gadget to a remote server that contains important information such as user ID numbers and profile data, it is important for the remote server to know that the data request has not been modified in any way by a malicious party.
...
OpenSocial 0.9 introduced the simpler osapi.http JavaScript library. An example of making a signed osapi.http request to fetch JSON data is below:<source lang="javascript">
Code Block |
---|
osapi.http.get({ |
...
Panel |
---|
'href' : 'http://www.example.com', 'format' : 'json', 'authz' : 'signed' }).execute(callback); |
</source>Please see the osapi.http documentation for more examples.
...
Using makeRequest has been deprecated, but is still widely available on many containers. An example of a signed makeRequest call to fetch JSON data is below:<source lang="javascript">
var params =
Code Block |
---|
var params = {}; |
...
params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON; |
...
params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED; |
...
gadgets.io.makeRequest("http://www.example.com", callback, params); |
</source>Please see the gadgets.io.makeRequest documentation for more examples.
...
A preload is executed at the same time that the gadget is rendered, so it effectively saves a whole round trip from the user of your application to the container where your app is running. Preloads are also fetched when the app is initially fetched, so you don't have to wait for an
Code Block |
---|
onload |
{{onload} event to fire before requesting remote data.
If you have a request that looks like the following:<source lang="javascript">
Code Block |
---|
osapi.http.get({'href' : 'http://www.example.com'}).execute(callback) |
</source>You can preload the content at
...
...
} by adding a
Code Block |
---|
<Preload> |
{{<Preload>} tag to your
Code Block |
---|
<ModulePrefs> |
{{<ModulePrefs>} section:<source lang="xml">
<ModulePrefs
Code Block |
---|
<ModulePrefs title="Preloads"> |
...
Panel |
---|
<Require feature="opensocial-0.9" /> <Preload href="http://www.example.com" /> </ModulePrefs> |
</source>When your application executes the
...
{{osapi.http
...
} call, this content will be returned instantly, without needing to hit your server again. Preloaded requests can also be signed if you need, by adding the optional
Code Block |
---|
authz |
{{authz} attribute to your
Code Block |
---|
Preload |
{{Preload} section:<source lang="xml">
<ModulePrefs
Code Block |
---|
<ModulePrefs title="Preloads"> |
...
Panel |
---|
<Require <Require feature="opensocial-0.9" /> <Preload href="http://www.example.com" authz="signed" /> </ModulePrefs> |
</source>There are a few more optimizations you can use to make preloads work even better:
- Turn off sending the viewer in signed requests. If you don't need the VIEWER ID for your signed request, disable it by adding
{{sign_viewer="false"} to yourCode Block
{{<Preload>} tag. This will allow the container to cache your request for a lot more requests. This is a critical improvement for profile pages!Code Block <Preload>
- You may disable sending the OWNER ID in signed preloads by adding
{{sign_owner="false"}.Code Block - Use multiple
{{<Preload>} tags if you have more than one request. You're not limited to oneCode Block <Preload>
{{<Preload>} tag, so preload whatever you can.Code Block <Preload>
- Restrict preloads to the correct view. If you only use a certain request in a specific view, restrict the preload to that view by adding a views attribute to your
{{<Preload>} tag. For example, to restrict a preload to the canvas view, addCode Block <Preload>
{{views="canvas"} to yourCode Block
{{<Preload>} tag. You can also specify multiple comma separated views, likeCode Block <Preload>
{{views="canvas,profile"}.Code Block
The following example makes three preloaded requests:
- The request to
<nowiki>http{{http://www.example.com/owner_data.json</nowiki>json} is signed with only the owner's ID number.Code Block - The request to
<nowiki>http{{http://www.example.com/global_view_data.json</nowiki>json} is a regular HTTP GET request and preloaded for all views.Code Block - The request to
<nowiki>http{{http://www.example.com/profile_view_data.json</nowiki>json} is a regular HTTP GET request, and is only made forCode Block
andCode Block profile
views.Code Block home
...
- {{profile} and {{home} views.
Code Block |
---|
<ModulePrefs title="Preloads"> |
...
Panel |
---|
<Require <Require feature="opensocial-0.9" /> <Require feature="views" /> <Preload href="http://www.example.com/owner_data.json" authz="signed" sign_viewer="false" /> <Preload href="http://www.example.com/global_view_data.json" /> <Preload href="http://www.example.com/profile_view_data.json" views="profile,home" /> </ModulePrefs> |
...
|
Please see the Gadgets XML Reference for more information.
...
The following example uses the content at
...
...
com} for the
Code Block |
---|
canvas |
{{canvas} view:<source lang="xml">
Code Block |
---|
<?xml version="1.0" encoding="UTF-8"?> |
...
Panel |
---|
<ModulePrefs <Module> <ModulePrefs title="Proxied Content"> <Require feature="opensocial-0.9" /> </ModulePrefs> <Content href="http://www.example.com" view="canvas"> </Content> </Module> |
...
|
For more information, see the Proxied Content /wiki/spaces/a/pages/527072 documentation.
Data Pipelining
...
Gadget authors can use Proxied Content to specify data to be fetched when the gadget is rendered using the
...
{{os:HttpRequest
...
} tag. The remote content is made available in the current gadget's OpenSocial data context.
The following example demonstrates fetching text content from
...
{{www.example.com
...
} and accessing it from both JavaScript and OpenSocial templates:<source lang="xml">
Code Block |
---|
<?xml version="1.0" encoding="UTF-8"?> |
...
Panel |
---|
<ModulePrefs <Module> <ModulePrefs title="Data Pipelining - httprequest"> <Require feature="opensocial-0.9" /> <Require feature="opensocial-data"/> <Require feature="opensocial-templates" /> </ModulePrefs> <Content type="html"> <![CDATA[ <script <script type="text/os-data" xmlns:os="http://ns.opensocial.org/2008/markup"> > <os:HttpRequest key="exampledata" href="http://www.example.com" format="text"/> </script> <script type="text/javascript"> var exampledata = var exampledata = opensocial.data.getDataContext().getDataSet('exampledata'); alert('Got: ' + exampledata.content); </script> <script type="text/os-template" xmlns:os="http://ns.opensocial.org/2008/markup" xmlns:osx="http://ns.opensocial.org/2009/extensions" require="exampledata"> Got Got ${exampledata.content} </script> ]]> </Content> </Module> |
</source>For more information, see the Data Pipelining /wiki/spaces/a/pages/526835 documentation.
Sending data using Data Pipelining and Proxied Content
While a:request signing can be used to pass an owner or viewer's ID to a remote server using a:JavaScript HTTP requests, your application may wish to transmit additional information, such as friends lists or profile data. Using Proxied Content and Data Pipelining enables this functionality. The following gadget makes a Data Pipelining call to
...
...
com}, sending the current viewer and viewer's friends:<source lang="xml">
Code Block |
---|
<?xml version="1.0" encoding="UTF-8"?> |
...
<Module xmlns:os="http://ns.opensocial.org/2008/markup"> |
...
Panel |
---|
<ModulePrefs <ModulePrefs title="Data Pipelining and Proxied Content"> <Require feature="opensocial-0.9" /> <Require feature="opensocial-data"/> </ModulePrefs> <Content href="http://www.example.com" authz="signed" sign_viewer="true"> <os:PeopleRequest key="viewer_friends" userId="@viewer" groupId="@friends" count="2"/> <os:ViewerRequest key="viewer" /> </Content> </Module> |
...
|
The server-side code at
...
...
com} gets a signed POST request, with the following JSON-encoded POST body:
<source lang="text">
[
Panel |
---|
Code Block |
[ { "id" : "viewer", "data" :{ { "id" : "1111111111", "isViewer" : true, "name" :{ { "familyName" : "Testington", "givenName" : "Alice" }, "thumbnailUrl" : "http://www.someexamplesocialnetwork.com/img/1111111111.png", "isOwner" :true } }, { true } }, { "id" : "viewer_friends", "data" :{ { "startIndex" : 0, "totalResults" : 65, "list" :[ { [ { "id" : "2222222222", "isViewer" : false, "name" :{ { "familyName" : "Testington", "givenName" : "Bob" }, }, "thumbnailUrl" : "http://www.someexamplesocialnetwork.com/img/2222222222.png", "isOwner" :false }, { false }, { "id" : "3333333333", "isViewer" : false, "name" :{ { "familyName" : "Testington", "givenName" : "Claire" }, }, "thumbnailUrl" : "http://www.someexamplesocialnetwork.com/img/3333333333.png", "isOwner" :false } ] } } |
...
false
}
]
}
}
]
|
By processing the POST body, the server can render a viewer-specific application view containing social data.
For more information, see the Data Pipelining /wiki/spaces/a/pages/526835 documentation.</html>