﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-风之力-随笔分类-ajax</title><link>http://www.blogjava.net/windforce/category/15612.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 07 Mar 2007 09:09:39 GMT</lastBuildDate><pubDate>Wed, 07 Mar 2007 09:09:39 GMT</pubDate><ttl>60</ttl><item><title>dwr回调传递多个参数</title><link>http://www.blogjava.net/windforce/archive/2007/03/06/102177.html</link><dc:creator>风之力</dc:creator><author>风之力</author><pubDate>Tue, 06 Mar 2007 07:24:00 GMT</pubDate><guid>http://www.blogjava.net/windforce/archive/2007/03/06/102177.html</guid><wfw:comment>http://www.blogjava.net/windforce/comments/102177.html</wfw:comment><comments>http://www.blogjava.net/windforce/archive/2007/03/06/102177.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/windforce/comments/commentRss/102177.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/windforce/services/trackbacks/102177.html</trackback:ping><description><![CDATA[
		<h1>
				<a name="Passingextradatatocallbacks-%E4%BC%A0%E9%80%92%E9%A2%9D%E5%A4%96%E7%9A%84%E6%95%B0%E6%8D%AE%E5%88%B0callback%E5%87%BD%E6%95%B0">
				</a>传递额外的数据到callback函数 </h1>
		<p>通常我们需要传递额外的数据到callback函数，但是因为所有的回调函数都只有一个参数(远程方法的返回结果)，这就需要一些小技巧了。 </p>
		<p>解决方案就是使用Javascript的<span class="nobr"><a title="Visit page outside Confluence" href="http://jibbering.com/faq/faq_notes/closures.html" rel="nofollow">闭包<sup><img class="rendericon" height="7" alt="" src="http://wiki.javascud.org/images/icons/linkext7.gif" width="7" align="absMiddle" border="0" /></sup></a></span>特性。 </p>
		<p>例如，你的回调函数原本需要像这个样子： </p>
		<div class="code">
				<div class="codeContent">
						<pre class="code-java">function callbackFunc(dataFromServer, dataFromBrowser) { 
<span class="code-comment">// 用dataFromServer和dataFromBrowser做些事情...... 
</span>}</pre>
				</div>
		</div>
		<p>那么你可以像这个组织你的函数： </p>
		<div class="code">
				<div class="codeContent">
						<pre class="code-java">
								<span class="code-keyword">var</span> dataFromBrowser = ...; 

<span class="code-comment">// 定义一个闭包函数来存储dataFromBrowser的引用，并调用dataFromServer 
</span><span class="code-keyword">var</span> callbackProxy = function(dataFromServer) { 
callbackFunc(dataFromServer, dataFromBrowser); 
}; 

<span class="code-keyword">var</span> callMetaData = { callback:callbackProxy }; 

Remote.method(params, callMetaData);</pre>
				</div>
		</div>
		<p>(调用元数据在<a title="Scripting Introduction" href="http://wiki.javascud.org/display/dwrcn/Scripting+Introduction">脚本介绍</a>中有解释) </p>
		<p>换句话说，现在你作为callback函数传递过来的不是一个真正的callback，他只是一个做为代理的闭包，用来传递客户端的数据。 </p>
		<p>你可以用更简介的形式： </p>
		<div class="code">
				<div class="codeContent">
						<pre class="code-java">
								<span class="code-keyword">var</span> dataFromBrowser = ...; 
Remote.method(params, { 
callback:function(dataFromServer) { 
callbackFunc(dataFromServer, dataFromBrowser); 
} 
});</pre>
				</div>
		</div>
<img src ="http://www.blogjava.net/windforce/aggbug/102177.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/windforce/" target="_blank">风之力</a> 2007-03-06 15:24 <a href="http://www.blogjava.net/windforce/archive/2007/03/06/102177.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Cross Site AJAX [转载]</title><link>http://www.blogjava.net/windforce/archive/2006/10/16/75439.html</link><dc:creator>风之力</dc:creator><author>风之力</author><pubDate>Mon, 16 Oct 2006 08:38:00 GMT</pubDate><guid>http://www.blogjava.net/windforce/archive/2006/10/16/75439.html</guid><wfw:comment>http://www.blogjava.net/windforce/comments/75439.html</wfw:comment><comments>http://www.blogjava.net/windforce/archive/2006/10/16/75439.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/windforce/comments/commentRss/75439.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/windforce/services/trackbacks/75439.html</trackback:ping><description><![CDATA[
		<p>一般情形下，为安全起见，浏览器不允许你在客户端通过XMLHttpRequest访问别的域(参考连接1,2)，即使是同一域的子域也不行，譬如www.joycode.com 到 blog.joycode.com。(你可以通过某些设置来访问子域，但因为这方法不是很通行，所有就不考虑了，但如果你感兴趣，参考连接2。) 
</p>
		<p>但很明显，在不少情形下，访问别的网站，获取别的网站的信息/服务是非常有用的，特别是在这个Web 2.0时代。 
</p>
		<p>常用的跨站访问的方法有3种(参考连接3，4)： 
</p>
		<ol>
				<li>在同一域的服务器端建立一个代理，浏览器向该代理网址发送请求，然后该代理向其他域的网址发请求，在获取回复后，或作处理或按原样发回到浏览器 
</li>
				<li>使用按需(On-Demand) Javascript 脚本。在页面内动态生成新的&lt;script&gt;，将其src属性指向别的网站的网址，这个网址返回的内容必须是合法的Javascript脚本，常用的是JSON消息。 
</li>
				<li>使用IFRAME。在页面内嵌或动态生成指向别的网站的IFRAME，然后这2个网页间可以通过改变对方的anchor hash fragment来传输消息。改变一个网页的anchor hash fragment并不会使浏览器重新装载网页，所以一个网页的状态得以保持，而网页本身则可以通过一个计时器(timer)来察觉自己anchor hash的变化，从而相应改变自己的状态(参考<a href="http://blog.joycode.com/saucer/archive/2006/09/13/83457.aspx">这个帖子</a>中提及的<a href="http://www.nikhilk.net/Entry.aspx?id=139" target="_blank">Nikhil Kothari的历史控件</a>中的方法)。 <a href="http://blog.monstuff.com/" target="_blank">Julien Couvreur</a>在他的《<a href="http://blog.monstuff.com/archives/000304.html" target="_blank">Cross-document messaging hack</a>》里描述了一个更复杂的应用情形，<br />"....<br />For example, if you have page A containing an iframe B in a different domain,then B can create a new iframe and load it with a url in the same domain as A. The url that is loaded doesn't generate a request to the server if it is properly cached and only the fragment identifier is used to pass changing information. Page A can now get the DOM handle on the new iframe and successfully retrieve the information transmitted in the url by B...." (大体这样，网页A包含了一个IFRAME B，B的网页来自一个不同的域。然后B页可以生成一个IFRAME C，把它指向与网页A同域的某个地址，因为是A与C同域，网页A可以访问C里的信息，反之亦然。) </li>
		</ol>
		<p>
				<a href="http://atlas.asp.net/Default.aspx?tabid=47">ASP.NET AJAX扩展(即Atlas)</a>提供了一个桥(bridge)机制让你在服务器端配置来访问别的网站，并同时支持POX和SOAP这2种协议。想了解其中细节，请参考Atlas文档里的<a href="http://atlas.asp.net/docs/Walkthroughs/DevScenarios/bridge.aspx" target="_blank">《Building Mash-ups with "Atlas"》</a>。当然你完全可以自己建立一个web service，通过它来访问其他网站并返回信息。 
</p>
		<p>据说，Atlas中的 IFrameExecutor 可以实现跨域的调用，我按照MSDN博客<a href="http://blogs.msdn.com/federaldev/default.aspx" target="_blank">Federal Developer Weblog</a>的这篇帖子<a href="http://blogs.msdn.com/federaldev/archive/2006/07/31/684229.aspx" target="_blank">《Calling web services hosted outside of your application with “Atlas”》</a>上的步骤试了一下，但在Windows 2003 Server SP1上得到却是“Access is denied”的错误信息。然后我下载了<a href="http://www.federaldeveloper.com/Shared%20Documents/Presentations%20by%20Marc%20Schweigert/CallAtlasWebServiceInDifferentProject.zip">该文中的项目</a>，试验的结果仍旧是“Access is denied”。也许需要改动一些浏览器中的什么设置才能成功，但这不是我的目的，我需要一个在普通设置下都能成功的例子。 
</p>
		<p>按需(On-Demand) Javascript脚本的实现是很简单的，譬如我有这样一个网页，(想测试的话，需要改动其中的网址) 
</p>
		<div style="MARGIN: 2em">
				<code>
						<p>&lt;html&gt;<br />&lt;head&gt;<br />&lt;script language="javascript" type="text/javascript"&gt;<br />function loadContent()<br />{<br />var s=document.createElement('SCRIPT');<br />s.src='<a href="http://www.anotherdomain.com/TestCrossJS.aspx?f=setDivContent';">http://www.anotherdomain.com/TestCrossJS.aspx?f=setDivContent';</a><br />document.body.appendChild(s);<br />} 
</p>
						<p>function setDivContent(v)<br />{<br />var dv = document.getElementById("dv");<br />dv.innerHTML = v; <br />}<br />&lt;/script&gt;<br />&lt;/head&gt;<br />&lt;body&gt;<br />&lt;div id="dv"&gt;&lt;/div&gt; 
</p>
						<p>&lt;input type="button" value="Click Me" onclick="loadContent()"&gt;<br />&lt;/body&gt;<br />&lt;/html&gt; </p>
				</code>
		</div>
		<p>其中的www.anotherdomain.com/TestCrossJS.aspx是这样的， 
</p>
		<div style="MARGIN: 2em">
				<code>
						<p>&lt;script language="C#" runat="server"&gt;<br />void Page_Load(object sender, EventArgs e)<br />{<br />  string f = Request.QueryString["f"];<br />  Response.Clear();<br />  Response.ContentType = "application/x-javascript";<br />  Response.Write(String.Format(@"<br />                   {0}('{1}');", <br />                   f,<br />                   DateTime.Now));<br />  Response.End();<br />}<br />&lt;/script&gt; </p>
				</code>
		</div>
		<p>点击“Click Me”按钮，生成一个新的script tag，下载对应的 Javascript 脚本，结束时回调其中的setDivContent()，从而更新网页上一个div的内容。 
</p>
		<p>IFRAME的方法好像很流行，除了<a href="http://manual.dojotoolkit.org/WikiHome/DojoDotBook/Book75" target="_blank">dojo工具包支持</a>外，据微软的<a href="http://www.25hoursaday.com/weblog/default.aspx" target="_blank">Dare Obasanjo</a>说(参考连接9)，<a href="http://www.25hoursaday.com/weblog/PermaLink.aspx?guid=3b03cf9d-b589-4838-806e-64efcc0a1a15" target="_blank">Windows Live Contacts Gadget使用了这个方法来获取Hotmail的address book</a>。最近，<a href="http://www.plaxo.com/" target="_blank">Plaxo</a>公司的开发人员 Joseph Smarr在七月的OSCON 2006会议上作了一个题为<a href="http://blog.plaxo.com/archives/2006/07/oscon_crosssite.html" target="_blank">《Cross-site Ajax: Challenges and Techniques for Building Rich Web 2.0 Mashups》</a>的讲座[来源：<a href="http://www.sitepoint.com/blogs/2006/07/28/oscon-2006-cross-site-ajax/" target="_blank">Kevin Yank--OSCON 2006: Cross-site Ajax</a>]，<a href="http://www.plaxo.com/api" target="_blank">他们将这个方法做成了一个平台</a>，允许合作伙伴间合作，他们开发的方案叫“The JavaScript Wormhole(虫洞)”，据说准备将其推广为一个标准。他讲座的PPT可以在<a href="http://blog.plaxo.com/archives/2006/07/oscon_crosssite.html" target="_blank">这里</a><a href="http://www.plaxo.com/css/api/Joseph-Smarr-Plaxo-OSCON-2006.ppt">下载</a>，里面对这个方案做了说明，非常值得看一下。 
</p>
		<p>现在将IFRAME的方法简单示范如下: 
</p>
		<p>1. <a href="http://domain1/TestCross.html:">http://domain1/TestCross.html:</a></p>
		<div style="MARGIN: 2em">
				<code>
						<p>&lt;html&gt;<br />&lt;head&gt;<br />&lt;script language="javascript" type="text/javascript"&gt;<br />var url = "<a href="http://domain2/TestCross.html&quot;;">http://domain2/TestCross.html"</a><br />var oldHash = null;<br />var timer = null; 
</p>
						<p>function getHash() <br />{<br />var hash = window.location.hash;<br />if ((hash.length &gt;= 1) &amp;&amp; (hash.charAt(0) == '#')) <br />{<br />hash = hash.substring(1);<br />} 
</p>
						<p>return hash;<br />}<br />function sendRequest()<br />{<br />var d = document;<br />var t = d.getElementById('request');<br />var f = d.getElementById('alienFrame');<br />f.src = url + "#" + t.value + "&lt;br/&gt;" + new Date();<br />} 
</p>
						<p>function setDivHtml(v)<br />{<br />var d = document;<br />var dv = d.getElementById('response');<br />dv.innerHTML = v;<br />} 
</p>
						<p>function idle()<br />{<br />var newHash = getHash(); 
</p>
						<p>if (newHash != oldHash)<br />{<br />setDivHtml(newHash);<br />oldHash = newHash;<br />} 
</p>
						<p>timer = window.setTimeout(idle, 100);<br />} 
</p>
						<p>function window.onload()<br />{<br />timer = window.setTimeout(idle, 100);<br />}<br />&lt;/script&gt;<br />&lt;/head&gt;<br />&lt;body&gt; 
</p>
						<p>请求：&lt;input type="text" id="request"&gt; &lt;input type="button" value="发送" onclick="sendRequest()" /&gt;&lt;br/&gt;<br />回复：&lt;div id="response"&gt;&lt;/div&gt; 
</p>
						<p>&lt;iframe id="alienFrame" src="<a href="http://domain2/TestCross.html&quot;">http://domain2/TestCross.html"</a>&gt;&lt;/iframe&gt; 
</p>
						<p>&lt;/body&gt;<br />&lt;/html&gt; </p>
				</code>
		</div>
		<p>2. <a href="http://domain2/TestCross.html:">http://domain2/TestCross.html:</a></p>
		<div style="MARGIN: 2em">
				<code>
						<p>&lt;html&gt;<br />&lt;head&gt;<br />&lt;script language="javascript" type="text/javascript"&gt;<br />var url = "<a href="http://domain1/TestCross.html&quot;;">http://domain1/TestCross.html"</a><br />var oldHash = null;<br />var timer = null; 
</p>
						<p>function getHash() <br />{<br />var hash = window.location.hash;<br />if ((hash.length &gt;= 1) &amp;&amp; (hash.charAt(0) == '#')) <br />{<br />hash = hash.substring(1);<br />} 
</p>
						<p>return hash;<br />}<br />function sendRequest()<br />{<br />var d = document;<br />var t = d.getElementById('request');<br />var f = parent;<br />//alert(f.document); //试着去掉这个注释，你会得到“Access is denied”<br />f.location.href = url + "#" + t.value + "&lt;br/&gt;" + new Date();<br />} 
</p>
						<p>function setDivHtml(v)<br />{<br />var d = document;<br />var dv = d.getElementById('response');<br />dv.innerHTML = v;<br />} 
</p>
						<p>function idle()<br />{<br />var newHash = getHash(); 
</p>
						<p>if (newHash != oldHash)<br />{<br />setDivHtml(newHash);<br />oldHash = newHash;<br />} 
</p>
						<p>timer = window.setTimeout(idle, 100);<br />} 
</p>
						<p>function window.onload()<br />{<br />timer = window.setTimeout(idle, 100);<br />}<br />&lt;/script&gt;<br />&lt;/head&gt;<br />&lt;body&gt; 
</p>
						<p>请求：&lt;input type="text" id="request"&gt; &lt;input type="button" value="发送" onclick="sendRequest()" /&gt;&lt;br/&gt;<br />回复：&lt;div id="response"&gt;&lt;/div&gt; 
</p>
						<p>&lt;/body&gt;<br />&lt;/html&gt; </p>
				</code>
		</div>
		<p>两个网页基本相同，第一个网页内嵌一个IFRAME，在点击“发送”按钮后，会将文本框里的内容通过hash fragment传给IFRAME。点击IFRAME里的“发送”按钮后，它会将文本框里的内容通过hash fragment传给父窗口。因为是只改动了hash fragment，浏览器不会重新load网页内容，这里使用了一个计时器来检测URL变化，如果变化了，就更新其中一个div的内容 。 
</p>
		<p>
		</p>
		<p>这个方法是不是个安全漏洞？考虑到微软的Windows Live都在使用这个方法，估计不是，<img src="http://blog.joycode.com/emoticons/emotion-1.gif" />。这个方法是不是很安全？考虑到这个方法只有在2个网站协作的情形才能成功，安全问题好像不是很大，除非其中涉及的网站本身有XSS的问题。</p>
		<p>【参考连接】 </p>
		<p>1. Security Considerations: Dynamic HTML<br /><a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/sec_dhtml.asp">http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/sec_dhtml.asp</a></p>
		<p>2. About Cross-Frame Scripting and Security<br /><a href="http://msdn.microsoft.com/library/default.asp?url=/workshop/author/om/xframe_scripting_security.asp">http://msdn.microsoft.com/library/default.asp?url=/workshop/author/om/xframe_scripting_security.asp</a></p>
		<p>3. Cross-Domain Proxy<br /><a href="http://ajaxpatterns.org/Cross-Domain_Proxy">http://ajaxpatterns.org/Cross-Domain_Proxy</a></p>
		<p>4. Cross Domain XMLHttpRequest using an IFrame Proxy<br /><a href="http://manual.dojotoolkit.org/WikiHome/DojoDotBook/Book75">http://manual.dojotoolkit.org/WikiHome/DojoDotBook/Book75</a></p>
		<p>5. Back Button Support for Atlas UpdatePanels<br /><a href="http://www.nikhilk.net/BackButtonSupport.aspx">http://www.nikhilk.net/BackButtonSupport.aspx</a></p>
		<p>6. Cross-document messaging hack<br /><a href="http://blog.monstuff.com/archives/000304.html">http://blog.monstuff.com/archives/000304.html</a></p>
		<p>7. Building Mash-ups with "Atlas"<br /><a href="http://atlas.asp.net/docs/Walkthroughs/DevScenarios/bridge.aspx">http://atlas.asp.net/docs/Walkthroughs/DevScenarios/bridge.aspx</a></p>
		<p>8. Calling web services hosted outside of your application with “Atlas”<br /><a href="http://blogs.msdn.com/federaldev/archive/2006/07/31/684229.aspx">http://blogs.msdn.com/federaldev/archive/2006/07/31/684229.aspx</a></p>
		<p>
				<a href="http://www.federaldeveloper.com/Shared%20Documents/Presentations%20by%20Marc%20Schweigert/CallAtlasWebServiceInDifferentProject.zip">http://www.federaldeveloper.com/Shared%20Documents/Presentations%20by%20Marc%20Schweigert/CallAtlasWebServiceInDifferentProject.zip</a>
		</p>
		<p>9. AJAX Tip: Passing Messages Between iframes <br /><a href="http://www.25hoursaday.com/weblog/PermaLink.aspx?guid=3b03cf9d-b589-4838-806e-64efcc0a1a15">http://www.25hoursaday.com/weblog/PermaLink.aspx?guid=3b03cf9d-b589-4838-806e-64efcc0a1a15</a></p>
		<p>10. OSCON Cross-site Ajax Slides<br /><a href="http://blog.plaxo.com/archives/2006/07/oscon_crosssite.html">http://blog.plaxo.com/archives/2006/07/oscon_crosssite.html</a></p>
		<p>
				<a href="http://www.plaxo.com/css/api/Joseph-Smarr-Plaxo-OSCON-2006.ppt">http://www.plaxo.com/css/api/Joseph-Smarr-Plaxo-OSCON-2006.ppt</a>
		</p>
		<p>11. OSCON 2006: Cross-site Ajax<br /><a href="http://www.sitepoint.com/blogs/2006/07/28/oscon-2006-cross-site-ajax/">http://www.sitepoint.com/blogs/2006/07/28/oscon-2006-cross-site-ajax/</a></p>
<img src ="http://www.blogjava.net/windforce/aggbug/75439.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/windforce/" target="_blank">风之力</a> 2006-10-16 16:38 <a href="http://www.blogjava.net/windforce/archive/2006/10/16/75439.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>