<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>非鱼观点-互联网观察 &#187; API开发</title>
	<atom:link href="http://www.unfish.net/archives/tag/api%e5%bc%80%e5%8f%91/feed" rel="self" type="application/rss+xml" />
	<link>http://www.unfish.net</link>
	<description>if(I&#039;m awake){I&#039;m writing code;}else{I&#039;m ready to write code;}</description>
	<lastBuildDate>Mon, 12 Jul 2010 13:16:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>校内/Manyou/Alisoft API应用开发Demo</title>
		<link>http://www.unfish.net/archives/337-20081025.html</link>
		<comments>http://www.unfish.net/archives/337-20081025.html#comments</comments>
		<pubDate>Sat, 25 Oct 2008 05:09:04 +0000</pubDate>
		<dc:creator>非鱼</dc:creator>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[API开发]]></category>
		<category><![CDATA[Manyou]]></category>
		<category><![CDATA[校内]]></category>
		<category><![CDATA[阿里软件]]></category>

		<guid isPermaLink="false">http://new.unfish.net/?p=337</guid>
		<description><![CDATA[其实要写个完整的Demo是挺困难的，而且目前我只做了Python的开发，没有写过其它版本，而且以我的习惯，我也不喜欢写完整的代码给别人去抄，所谓授之以鱼不如授之以渔。写个自然语言的版本吧，写起来简单，看的人也容易使用自己喜欢的语言来搞定。
为什么把三个放在一起呢，其实它们的API区别不大，流程都是一样的，只是参数名字的区别而已。
API的工作流程如下：（这些东西三个网站的开发手册里都有）
用户登录到校内/Manyou/Alisoft以后，进入他的应用列表，可以看到他安装过的所有的应用，点击某个应用的时候，就会跳到一个特定的地址。校内和Manyou有XNML/MYML的开发方式，在这种方式下，用户的每次点击都是点到他们的地址上，在他们的服务器上把请求转发到你的网址。这种情况下你在自己的网站上是不能用Session或者Cookie来记住用户的，因为所有的用户都是同一个地方发来的请求。所以你只能每个页面都要从他们传过来的参数里获取当前用户的信息。而IFrame的方式要简单的多，只要给他们一个入口，他们就会生成一个IFrame把参数传入你这个入口地址，以后用户的所有操作都是在你的网站上，所以只要这个入口页面处理查询用户信息并用你自己的Cookie来登录，剩下的跟其它的页面逻辑是一样的。Alisoft也是这样做的。所以这里我只讲IFrame方式。
校内和Manyou是跳到它自己域名的一个URL，然后生成一个IFrame链接到你网站的一个地址，Alisoft则是直接跳到你的网站上的地址。跳到这个地址的时候会带一些参数过来，比如当前用户的ID，SessionID，还有其它一些参数，但是真正有用的就是这两个。凭这两个参数，你就可以反过来去查询该用户的所有信息。
所以你首先需要一个处理登录的页面，接收他传过来的参数，在参数里获取用户ID，SessionID，然后查询用户的真实身份和用户名，如果验证是从API应用里点过来的，就在你自己的站上查询这个用户ID是否已存在，如果存在就取出来设他的Cookie或Session让他登录，如果不存在，就生成一个新用户，跟这个用户ID绑定起来，然后让他登录就行了。用户再点你其它的链接，就是你网站的一般逻辑而已了。
各种语言都有自己发POST请求的方式，需要自己去看看帮助了。
查询用户信息的方式：
校内的：只需要在REQUEST里获取这两个参数：xn_sig_user，xn_sig_session_key，然后往这个地址http://api.xiaonei.com/restserver.do Post这些参数：
api_key：你的应用的Key，官方给出来的那个串，method：&#8217;xiaonei.users.getInfo&#8217;，session_key：就是前面获取的这个，call_id：0，sig：空字符串，v: ‘1.0’，fields：&#8217;name,sex&#8217;，uids：前面获取的那个user。
单引号括起来的就是固定字符串。至于sig，本来它应该是个用来验证请求身份是否合法的加密串，但是校内现在并没有用到，所以传个空的过去就行。如果用户是合法的，你就会得到一个包含&#60;name&#62;和&#60;sex&#62;的XML文本，剩下的应该是你自己的问题啦。
Manyou的：你需要获取三个参数：my_sig_uId，my_sig_sessionId，my_sig_prefix，前两个跟校内一样，最后一个是该用户实际所在站点的URL（因为Manyou是一个应用服务器给所有的UCenter子站服务的）。当然还有个参数my_sig_key可以用来验证传过来的参数是否合法，如果你只需要获取用户ID，不需要知道他的名字，就用这个参数来验证的话就可以省却一次POST的时间了。
然后需要需要往这个地址http://api.manyou.com/openapi.php POST这些参数：
api_key：你的应用的key，官方给的，format：&#8217;JSON&#8217;，（否则默认返回PHP格式的），method：&#8217;user.getinfo&#8217;，session_key:前面获取的sessionId，v:&#8217;0.1&#8242;，args[fields]: &#8216;name,sex&#8217;，args[uids]:前面获取的uId，sig：加密字符串。
重点在这个加密字符串的计算上，它的算法是把通用参数按字母排序，再加上你所调用的这个API方法的专用参数，再加上你的应用的安全码（申请的时候给的），拼成一个字符串算出来的MD5。比如上面这个方法，拼字符串就是：
&#8216;api_key=&#8217;+apikey+&#8217;&#38;format=JSON&#38;method=user.getinfo&#38;session_key=&#8217;+my_sig_sessionId+&#8217;&#38;v=0.1&#38;args[fields]=name,sex&#38;args[uids]=&#8217;+userid+&#8217;&#38;&#8217;+code
注意我中间引号外面的是自己的变量名，别照抄。最后的code就是你的安全码。对这个字符串算一个MD5就是前面需要POST的那个sig参数的值了。
这样如果请求合法，你会得到一个JSON格式的返回，格式为&#34;name&#34;:&#34;用户名&#34;,&#34;sex&#34;:&#34;性别&#34;。你只要分解字符串就可以拿到这个用户名了。剩下的就是自己的问题了。
Alisoft的：跟Manyou的非常相似
你需要获取三个参数：user_id，app_instance_id（就是sessionID），token（有特殊用途）。
然后往这个地址http://sipdev.alisoft.com/sip/rest （正式上线后把域名里的dev去掉）POST以下参数：
appId：你的应用的编号（官方给出的），appInstanceId：前面给出的，sip_apiname : &#8216;alisoft.validateUser&#8217;，sip_appkey：跟appId一样，sip_timestamp：当前时间字符串，格式为2008-10-01 08:00:00，token：前面获取的那个，userId：前面获取的那个，sip_sign：加密字符串。
加密字符串的计算方法跟Manyou类似，但是串联字符串的时候没有&#38;和=，而是把所有的内容串在一起，而且你的安全码是放在字符串的最前面的，前面这个方法的字符串就是：
code+&#8217;appId&#8217;+appid+&#8217;appInstanceId&#8217;+instance+&#8217;sip_apinamealisoft.validateUser&#8217;+&#8217;sip_appkey&#8217;+appid+&#8217;sip_timestamp&#8217;+now +&#8217;token&#8217;+token+&#8217;userId&#8217;+userid
code是你的安全码，now就是前面说的时间字符串，其它的变量一看就知道了。
返回的内容只有一个&#60;String&#62;1&#60;/String&#62;，包含这个就说明该用户是合法的，但是并不会返回他的用户名，如果你想获取用户名的话，还得再去调用另外一个API，自己去看看官方的文档吧（因为他的用户可能是淘宝的，也可能是阿里巴巴的）。调用方法是一样的。
]]></description>
			<content:encoded><![CDATA[<p>其实要写个完整的Demo是挺困难的，而且目前我只做了Python的开发，没有写过其它版本，而且以我的习惯，我也不喜欢写完整的代码给别人去抄，所谓授之以鱼不如授之以渔。写个自然语言的版本吧，写起来简单，看的人也容易使用自己喜欢的语言来搞定。</p>
<p>为什么把三个放在一起呢，其实它们的API区别不大，流程都是一样的，只是参数名字的区别而已。</p>
<p>API的工作流程如下：（这些东西三个网站的开发手册里都有）</p>
<p>用户登录到校内/Manyou/Alisoft以后，进入他的应用列表，可以看到他安装过的所有的应用，点击某个应用的时候，就会跳到一个特定的地址。校内和Manyou有XNML/MYML的开发方式，在这种方式下，用户的每次点击都是点到他们的地址上，在他们的服务器上把请求转发到你的网址。这种情况下你在自己的网站上是不能用Session或者Cookie来记住用户的，因为所有的用户都是同一个地方发来的请求。所以你只能每个页面都要从他们传过来的参数里获取当前用户的信息。而IFrame的方式要简单的多，只要给他们一个入口，他们就会生成一个IFrame把参数传入你这个入口地址，以后用户的所有操作都是在你的网站上，所以只要这个入口页面处理查询用户信息并用你自己的Cookie来登录，剩下的跟其它的页面逻辑是一样的。Alisoft也是这样做的。所以这里我只讲IFrame方式。</p>
<p>校内和Manyou是跳到它自己域名的一个URL，然后生成一个IFrame链接到你网站的一个地址，Alisoft则是直接跳到你的网站上的地址。跳到这个地址的时候会带一些参数过来，比如当前用户的ID，SessionID，还有其它一些参数，但是真正有用的就是这两个。凭这两个参数，你就可以反过来去查询该用户的所有信息。</p>
<p>所以你首先需要一个处理登录的页面，接收他传过来的参数，在参数里获取用户ID，SessionID，然后查询用户的真实身份和用户名，如果验证是从API应用里点过来的，就在你自己的站上查询这个用户ID是否已存在，如果存在就取出来设他的Cookie或Session让他登录，如果不存在，就生成一个新用户，跟这个用户ID绑定起来，然后让他登录就行了。用户再点你其它的链接，就是你网站的一般逻辑而已了。</p>
<p>各种语言都有自己发POST请求的方式，需要自己去看看帮助了。</p>
<p>查询用户信息的方式：</p>
<p>校内的：只需要在REQUEST里获取这两个参数：xn_sig_user，xn_sig_session_key，然后往这个地址<a href="http://api.xiaonei.com/restserver.do" title="http://api.xiaonei.com/restserver.do">http://api.xiaonei.com/restserver.do</a> Post这些参数：</p>
<p>api_key：你的应用的Key，官方给出来的那个串，method：&#8217;xiaonei.users.getInfo&#8217;，session_key：就是前面获取的这个，call_id：0，sig：空字符串，v: ‘1.0’，fields：&#8217;name,sex&#8217;，uids：前面获取的那个user。</p>
<p>单引号括起来的就是固定字符串。至于sig，本来它应该是个用来验证请求身份是否合法的加密串，但是校内现在并没有用到，所以传个空的过去就行。如果用户是合法的，你就会得到一个包含&lt;name&gt;和&lt;sex&gt;的XML文本，剩下的应该是你自己的问题啦。</p>
<p>Manyou的：你需要获取三个参数：my_sig_uId，my_sig_sessionId，my_sig_prefix，前两个跟校内一样，最后一个是该用户实际所在站点的URL（因为Manyou是一个应用服务器给所有的UCenter子站服务的）。当然还有个参数my_sig_key可以用来验证传过来的参数是否合法，如果你只需要获取用户ID，不需要知道他的名字，就用这个参数来验证的话就可以省却一次POST的时间了。</p>
<p>然后需要需要往这个地址<a href="http://api.manyou.com/openapi.php" title="http://api.manyou.com/openapi.php">http://api.manyou.com/openapi.php</a> POST这些参数：</p>
<p>api_key：你的应用的key，官方给的，format：&#8217;JSON&#8217;，（否则默认返回PHP格式的），method：&#8217;user.getinfo&#8217;，session_key:前面获取的sessionId，v:&#8217;0.1&#8242;，args[fields]: &#8216;name,sex&#8217;，args[uids]:前面获取的uId，sig：加密字符串。</p>
<p>重点在这个加密字符串的计算上，它的算法是把通用参数按字母排序，再加上你所调用的这个API方法的专用参数，再加上你的应用的安全码（申请的时候给的），拼成一个字符串算出来的MD5。比如上面这个方法，拼字符串就是：</p>
<p>&#8216;api_key=&#8217;+apikey+&#8217;&amp;format=JSON&amp;method=user.getinfo&amp;session_key=&#8217;+my_sig_sessionId+&#8217;&amp;v=0.1&amp;args[fields]=name,sex&amp;args[uids]=&#8217;+userid+&#8217;&amp;&#8217;+code</p>
<p>注意我中间引号外面的是自己的变量名，别照抄。最后的code就是你的安全码。对这个字符串算一个MD5就是前面需要POST的那个sig参数的值了。</p>
<p>这样如果请求合法，你会得到一个JSON格式的返回，格式为&quot;name&quot;:&quot;用户名&quot;,&quot;sex&quot;:&quot;性别&quot;。你只要分解字符串就可以拿到这个用户名了。剩下的就是自己的问题了。</p>
<p>Alisoft的：跟Manyou的非常相似</p>
<p>你需要获取三个参数：user_id，app_instance_id（就是sessionID），token（有特殊用途）。</p>
<p>然后往这个地址<a href="http://sipdev.alisoft.com/sip/rest" title="http://sipdev.alisoft.com/sip/rest">http://sipdev.alisoft.com/sip/rest</a> （正式上线后把域名里的dev去掉）POST以下参数：</p>
<p>appId：你的应用的编号（官方给出的），appInstanceId：前面给出的，sip_apiname : &#8216;alisoft.validateUser&#8217;，sip_appkey：跟appId一样，sip_timestamp：当前时间字符串，格式为2008-10-01 08:00:00，token：前面获取的那个，userId：前面获取的那个，sip_sign：加密字符串。</p>
<p>加密字符串的计算方法跟Manyou类似，但是串联字符串的时候没有&amp;和=，而是把所有的内容串在一起，而且你的安全码是放在字符串的最前面的，前面这个方法的字符串就是：</p>
<p>code+&#8217;appId&#8217;+appid+&#8217;appInstanceId&#8217;+instance+&#8217;sip_apinamealisoft.validateUser&#8217;+&#8217;sip_appkey&#8217;+appid+&#8217;sip_timestamp&#8217;+now +&#8217;token&#8217;+token+&#8217;userId&#8217;+userid</p>
<p>code是你的安全码，now就是前面说的时间字符串，其它的变量一看就知道了。</p>
<p>返回的内容只有一个&lt;String&gt;1&lt;/String&gt;，包含这个就说明该用户是合法的，但是并不会返回他的用户名，如果你想获取用户名的话，还得再去调用另外一个API，自己去看看官方的文档吧（因为他的用户可能是淘宝的，也可能是阿里巴巴的）。调用方法是一样的。</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.unfish.net/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.unfish.net/archives/337-20081025.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Manyou API开发感受</title>
		<link>http://www.unfish.net/archives/331-20080915.html</link>
		<comments>http://www.unfish.net/archives/331-20080915.html#comments</comments>
		<pubDate>Mon, 15 Sep 2008 07:56:42 +0000</pubDate>
		<dc:creator>非鱼</dc:creator>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[API开发]]></category>
		<category><![CDATA[Manyou]]></category>

		<guid isPermaLink="false">http://new.unfish.net/?p=331</guid>
		<description><![CDATA[做完了校内的API版本以后，本想做海内和开心网的，找半天没有一点关于API的消息，似乎从来没有公布过一样。但是里面的那些应用又不像全部是公司开发的，难道属于内测阶段？
于是转去研究UCenter的API－Manyou。初看起来，Manyou的API完成度更高，文档也更细，而且已经有了MYQL和MYJS，比校内的更加成熟。结果，真正开发起来，才发现简直是场恶梦。
注册新程序的流程跟校内一样，但是少一个映射URL的选项，也就是说你的程序没有短路径。
API的函数和参数的说明都不少，但是偏偏没有如何调用。（有，但是是PHP版的，而且是PHP开发包的调用方法，如果你想自己做Post请求，Sorry，即找不到服务器地址，也找不到接收到的参数的说明。）
Python已经有了一个开发包，结果装上以后却说有一个函数未定义，启动不起来。
尝试了N多种方法，都没有办法成功的发送一个Post。
然后放弃了这种方法，只接收用户ID，不打算进行验证了。界面终于显示出来了。又发现其它页面的相对链接都不对了。又是一阵调试加猜测，总算找对了方法，把链接都改成相对于你的目录的链接，但是又不是相对链接，而是写绝对链接。
最后，看起来所有的页面都显示正确了，但是一个Form的Post又遇到了困难。我没办法让这个Form往正确的地址Post。换了多种方法，始终提示Bad Request。而且，Form里面被插入的隐藏变量居然跟Get的时候不一样，没有my_sig_uid字段……
算了，放弃了。浪费我一天的时间。
]]></description>
			<content:encoded><![CDATA[<p>做完了校内的API版本以后，本想做海内和开心网的，找半天没有一点关于API的消息，似乎从来没有公布过一样。但是里面的那些应用又不像全部是公司开发的，难道属于内测阶段？</p>
<p>于是转去研究UCenter的API－Manyou。初看起来，Manyou的API完成度更高，文档也更细，而且已经有了MYQL和MYJS，比校内的更加成熟。结果，真正开发起来，才发现简直是场恶梦。</p>
<p>注册新程序的流程跟校内一样，但是少一个映射URL的选项，也就是说你的程序没有短路径。</p>
<p>API的函数和参数的说明都不少，但是偏偏没有如何调用。（有，但是是PHP版的，而且是PHP开发包的调用方法，如果你想自己做Post请求，Sorry，即找不到服务器地址，也找不到接收到的参数的说明。）</p>
<p>Python已经有了一个开发包，结果装上以后却说有一个函数未定义，启动不起来。</p>
<p>尝试了N多种方法，都没有办法成功的发送一个Post。</p>
<p>然后放弃了这种方法，只接收用户ID，不打算进行验证了。界面终于显示出来了。又发现其它页面的相对链接都不对了。又是一阵调试加猜测，总算找对了方法，把链接都改成相对于你的目录的链接，但是又不是相对链接，而是写绝对链接。</p>
<p>最后，看起来所有的页面都显示正确了，但是一个Form的Post又遇到了困难。我没办法让这个Form往正确的地址Post。换了多种方法，始终提示Bad Request。而且，Form里面被插入的隐藏变量居然跟Get的时候不一样，没有my_sig_uid字段……</p>
<p>算了，放弃了。浪费我一天的时间。</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.unfish.net/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.unfish.net/archives/331-20080915.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>校内API开发简易指南</title>
		<link>http://www.unfish.net/archives/329-20080910.html</link>
		<comments>http://www.unfish.net/archives/329-20080910.html#comments</comments>
		<pubDate>Wed, 10 Sep 2008 00:52:32 +0000</pubDate>
		<dc:creator>非鱼</dc:creator>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[API开发]]></category>
		<category><![CDATA[校内]]></category>

		<guid isPermaLink="false">http://new.unfish.net/?p=329</guid>
		<description><![CDATA[是时候研究一下国内的开放式API了，所以抽时间搞了一下，先从校内下手吧，相对来讲他的资料算是最多的了。但是即使如此，想从零开始写一个应用出来，还真是花了我不少功夫。资料实在是太难找了。校内的API从6、7月份就出来了，还弄了个专门的Wiki作为开放平台的门户，但是里面的资料出奇的少，除了对几个api函数的说明，对xnml的简单说明，其它的几乎为0。所谓的一个上手指南只讲了怎么注册用户和怎么注册程序，注册完以后的开放过程却一点也没提。想根据这份东西写个真正的应用出来，简直是不可能的任务。没办法，上Google，上社区，上应用的论坛，一篇篇帖子里找线索，最后总算是把一个应用给凑出来了。
如此糟糕的技术支持能力，直接决定了校内API应用的未来。
开发过程简介：
首先需要注册成校内用户，然后在自己的菜单上有个应用，添加一个“开发者”应用，这里面包括一个社区，一些开发所需要的链接。进入这个应用以后，可以看到一个申请开发许可证的按钮，点击就进入设置应用属性的环节，起名字，定URL之类的。（这一步在校内的Wiki上是有说明的。）有个安装到校内的选项，默认是否，结果选了以后我的应用就变成了外部应用，在校内只提供一个链接进入而已，这当然不行了。当我把应用删了重新添加的时候，原来使用的那个URL被占用了，无耐，换了个更难看的URL。应用还有一个重要的属性，就是运行状态，是以iframe形式还是xnml形式，这个待会再讲。第一次建议先选iframe形式，这个是随时可以修改的。
这些东西都设置完，应用就生成了。你会得到一个api_key，一个secret key，不过这两个东西都没什么用。
校内应用的工作原理：
如果是xnml方式的应用，用户访问apps.xiaonei.com/xxxxx/yyyyy这样一个地址的时候，xxxxx代表你申请一个应用的时候自己定义的那个URL，校内的API服务器会在后台将用户对该页面的请求（包括所有参数）转发给你的应用，也就是你申请应用的时候填的那个自己的应用地址。如果你的应用在你的服务器上是www.aaa.com/xxxxx/这样一个目录，那么上面这个请求就会被转发到www.aaa.com/xxxxx/yyyyy这里，不管yyyyy是个html页面还是个目录形式。转发的同时，还会多几个参数过来，包括当前用户的id，当前用户的sessionid，还有你的api key。你后续的所有的页面的链接，都要写成以apps.xiaonei.com开头的地址，由它来转发请求。
如果是iframe的应用就简单多了，海内直接生成一个iframe，把你注册时填的那个起始地址放进去，同时包括前面说的几个相同的参数。剩下的事情他们就不管了。
因为每次请求都是校内的服务器发给你，所以你的服务器上写Cookie或者session之类的东西是没有用的，必须每次取得这几个参数来决定当前用户是哪一个。（校内在这里有一个极其严重的设计失误，那就是没有用到创建程序时生成的那个secret key。校内发过来的这三个参数只能帮你确定是哪一个userid发过来的请求，而这三个参数之间是没有什么关联性的，比如你无法根据sessionid来判断这个userid是否合法。而在iframe状态的应用里，这三个参数直接暴露在浏览器代码里，用户只要复制下来，把userid改成另外一个数字放到浏览器地址栏里就OK了。现在，如果你想确保访问用户的合法性，就必须要通过校内的API调用，到他的服务器上去，把这三个参数发过去，看它的返回结果，多一次网络调用所带来的时间损失，远远大于任何的数据库运算或者数字运算。实际上，校内只要加上第四个参数，也就是你的secret key和其中任何一个参数合并后的md5码，你在取值以后用同样的算法生成md5码，比较一下跟传过来的值是否相等就OK了，完全不需要为了验证用户合法性而增加一次网络调用。更可恶的是，每个页面你都要做一次这样的网络调用。当然，你也可以在验证合法以后用自己的服务器保存一下userid和sessionid的对应关系，下次请求如果仍然是这两个数值就不用再网络验证了，但是这又增加了无谓的数据库调用。）
你已经拿到了用户在校内上的用户ID，并且确认他已经成功登录校内，接下来就是处理你自己的业务逻辑。比如在你的数据库里新增加一个用户，并绑定到这个校内ID上，然后对该用户进行某些操作。最后就是返回页面内容。
这里就到了iframe和xnml模式的区别。如果是iframe模式，你返回的页面内容直接显示在iframe里，那自由度就大多了，跟普通的网页一样，想怎么做就怎么做。不过要小心iframe跨域的js问题。
如果是xnml模式，你返回的内容（还是普通的html，但是没有body标签了）是由校内的api服务器接收到的，他们对内容进行解析，然后显示在自己的层里，展现给用户。为了防止一些非法操作，xnml规定了哪些html语法是合法的，如果出现不合法的语法，会直接报错。（这里又缺少一个可用的debug方式，一旦在这个步骤出现页面错误，极难调试。）Wiki的文档里写了这里是不允许出现自己的css语法的，但是实际上现在又是可以用css的，至少style和class两个关键字都是允许的。除了普通的html语法，xnml还定义了一些他自己的语法，通过这些语法，你可以在页面上直接显示出用户的姓名头像链接好友等等信息，而无需在你的程序里通过API调用去获取。
如果你要使用form来post数据，把form的action定义成相对路径，相对于你的这个应用的实际路径，比如，如果你的原始action应该是www.aaa.com/xxxxx/save.jsp，那么只要写action=&#8217;save.jsp&#8217;就可以了，在显示出来的时候，校内会将它替换成他们自己的相对路径，然后转发到正确的地址。
最后说说最有技术味道的东西，对校内API的调用。
现在校内一共只公开了为数不多的几个API，可以获取用户信息，好友信息，给用户发通知，现在还可以增加用户的新鲜事。对这些API的用户方式都是通过Post来实现的，Post的地址是固定的，就是这个地址：http://api.xiaonei.com/restserver.do，你需要对这个地址进行Post，发送几个参数过去，包括api_key，session_key，也就是校内传过来的那两个值，还有method，就是你要调用的方法名，然后不同的方法需要使用不同的参数，这些就可以去看校内的API文档了。这些参数Post过去以后，校内会返回一个xml，（虽然所有的调用都有个response格式的参数，可以选择xml还是json，但是，即使你选了json，它还是返回xml。）xml里要么包含错误码，要么，包含了你需要得到的信息，自己解析一下就行了。
所有的调用过程，包括你返回的参数和传递的参数，还有校内给你的参数，全部是utf8格式的，包括你生成的html。
这里只是一个开发过程的简单描述，不涉及代码，有兴趣的可以去看看校内自己的示例代码，是java的。有必要的话我也可以用代码的方式来写个demo，看大家的需要了。（论坛上面的hello world的demo对于实际开发的帮助几乎为0）。
]]></description>
			<content:encoded><![CDATA[<p>是时候研究一下国内的开放式API了，所以抽时间搞了一下，先从校内下手吧，相对来讲他的资料算是最多的了。但是即使如此，想从零开始写一个应用出来，还真是花了我不少功夫。资料实在是太难找了。校内的API从6、7月份就出来了，还弄了个专门的Wiki作为开放平台的门户，但是里面的资料出奇的少，除了对几个api函数的说明，对xnml的简单说明，其它的几乎为0。所谓的一个上手指南只讲了怎么注册用户和怎么注册程序，注册完以后的开放过程却一点也没提。想根据这份东西写个真正的应用出来，简直是不可能的任务。没办法，上Google，上社区，上应用的论坛，一篇篇帖子里找线索，最后总算是把一个应用给凑出来了。</p>
<p>如此糟糕的技术支持能力，直接决定了校内API应用的未来。</p>
<p>开发过程简介：</p>
<p>首先需要注册成校内用户，然后在自己的菜单上有个应用，添加一个“开发者”应用，这里面包括一个社区，一些开发所需要的链接。进入这个应用以后，可以看到一个申请开发许可证的按钮，点击就进入设置应用属性的环节，起名字，定URL之类的。（这一步在校内的Wiki上是有说明的。）有个安装到校内的选项，默认是否，结果选了以后我的应用就变成了外部应用，在校内只提供一个链接进入而已，这当然不行了。当我把应用删了重新添加的时候，原来使用的那个URL被占用了，无耐，换了个更难看的URL。应用还有一个重要的属性，就是运行状态，是以iframe形式还是xnml形式，这个待会再讲。第一次建议先选iframe形式，这个是随时可以修改的。<span id="more-329"></span></p>
<p>这些东西都设置完，应用就生成了。你会得到一个api_key，一个secret key，不过这两个东西都没什么用。</p>
<p>校内应用的工作原理：</p>
<p>如果是xnml方式的应用，用户访问apps.xiaonei.com/xxxxx/yyyyy这样一个地址的时候，xxxxx代表你申请一个应用的时候自己定义的那个URL，校内的API服务器会在后台将用户对该页面的请求（包括所有参数）转发给你的应用，也就是你申请应用的时候填的那个自己的应用地址。如果你的应用在你的服务器上是www.aaa.com/xxxxx/这样一个目录，那么上面这个请求就会被转发到www.aaa.com/xxxxx/yyyyy这里，不管yyyyy是个html页面还是个目录形式。转发的同时，还会多几个参数过来，包括当前用户的id，当前用户的sessionid，还有你的api key。你后续的所有的页面的链接，都要写成以apps.xiaonei.com开头的地址，由它来转发请求。</p>
<p>如果是iframe的应用就简单多了，海内直接生成一个iframe，把你注册时填的那个起始地址放进去，同时包括前面说的几个相同的参数。剩下的事情他们就不管了。</p>
<p>因为每次请求都是校内的服务器发给你，所以你的服务器上写Cookie或者session之类的东西是没有用的，必须每次取得这几个参数来决定当前用户是哪一个。（校内在这里有一个极其严重的设计失误，那就是没有用到创建程序时生成的那个secret key。校内发过来的这三个参数只能帮你确定是哪一个userid发过来的请求，而这三个参数之间是没有什么关联性的，比如你无法根据sessionid来判断这个userid是否合法。而在iframe状态的应用里，这三个参数直接暴露在浏览器代码里，用户只要复制下来，把userid改成另外一个数字放到浏览器地址栏里就OK了。现在，如果你想确保访问用户的合法性，就必须要通过校内的API调用，到他的服务器上去，把这三个参数发过去，看它的返回结果，多一次网络调用所带来的时间损失，远远大于任何的数据库运算或者数字运算。实际上，校内只要加上第四个参数，也就是你的secret key和其中任何一个参数合并后的md5码，你在取值以后用同样的算法生成md5码，比较一下跟传过来的值是否相等就OK了，完全不需要为了验证用户合法性而增加一次网络调用。更可恶的是，每个页面你都要做一次这样的网络调用。当然，你也可以在验证合法以后用自己的服务器保存一下userid和sessionid的对应关系，下次请求如果仍然是这两个数值就不用再网络验证了，但是这又增加了无谓的数据库调用。）</p>
<p>你已经拿到了用户在校内上的用户ID，并且确认他已经成功登录校内，接下来就是处理你自己的业务逻辑。比如在你的数据库里新增加一个用户，并绑定到这个校内ID上，然后对该用户进行某些操作。最后就是返回页面内容。</p>
<p>这里就到了iframe和xnml模式的区别。如果是iframe模式，你返回的页面内容直接显示在iframe里，那自由度就大多了，跟普通的网页一样，想怎么做就怎么做。不过要小心iframe跨域的js问题。</p>
<p>如果是xnml模式，你返回的内容（还是普通的html，但是没有body标签了）是由校内的api服务器接收到的，他们对内容进行解析，然后显示在自己的层里，展现给用户。为了防止一些非法操作，xnml规定了哪些html语法是合法的，如果出现不合法的语法，会直接报错。（这里又缺少一个可用的debug方式，一旦在这个步骤出现页面错误，极难调试。）Wiki的文档里写了这里是不允许出现自己的css语法的，但是实际上现在又是可以用css的，至少style和class两个关键字都是允许的。除了普通的html语法，xnml还定义了一些他自己的语法，通过这些语法，你可以在页面上直接显示出用户的姓名头像链接好友等等信息，而无需在你的程序里通过API调用去获取。</p>
<p>如果你要使用form来post数据，把form的action定义成相对路径，相对于你的这个应用的实际路径，比如，如果你的原始action应该是www.aaa.com/xxxxx/save.jsp，那么只要写action=&#8217;save.jsp&#8217;就可以了，在显示出来的时候，校内会将它替换成他们自己的相对路径，然后转发到正确的地址。</p>
<p>最后说说最有技术味道的东西，对校内API的调用。</p>
<p>现在校内一共只公开了为数不多的几个API，可以获取用户信息，好友信息，给用户发通知，现在还可以增加用户的新鲜事。对这些API的用户方式都是通过Post来实现的，Post的地址是固定的，就是这个地址：http://api.xiaonei.com/restserver.do，你需要对这个地址进行Post，发送几个参数过去，包括api_key，session_key，也就是校内传过来的那两个值，还有method，就是你要调用的方法名，然后不同的方法需要使用不同的参数，这些就可以去看校内的API文档了。这些参数Post过去以后，校内会返回一个xml，（虽然所有的调用都有个response格式的参数，可以选择xml还是json，但是，即使你选了json，它还是返回xml。）xml里要么包含错误码，要么，包含了你需要得到的信息，自己解析一下就行了。</p>
<p>所有的调用过程，包括你返回的参数和传递的参数，还有校内给你的参数，全部是utf8格式的，包括你生成的html。</p>
<p>这里只是一个开发过程的简单描述，不涉及代码，有兴趣的可以去看看校内自己的示例代码，是java的。有必要的话我也可以用代码的方式来写个demo，看大家的需要了。（论坛上面的hello world的demo对于实际开发的帮助几乎为0）。</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.unfish.net/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.unfish.net/archives/329-20080910.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
