javascript的跨域get很容易搞 定,但是跨域post就有點複雜了,今天無意看到大牛“張宴”的文章:http://blog.s135.com/ajaxcdr/ ,思路很不錯,轉載於此(其實這個思路要是看懂了,也很容易藉助silverlight實現)
最近的一個項目中,需要通過 JavaScript 提交表單資料到另一個網域名稱下的PHP介面(因為資料較大,需要HTTP POST方式提交),並擷取PHP介面的傳回值,在頁面無重新整理、無跳轉的情況下,更新div標籤內的內容。
瀏覽器出於安全考慮,是不允許JavaScript代碼進行跨網域作業。JavaScript 和 AJAX 跨域訪問分為兩大類,一是本域和子域的互動,二是本域和其他域的互動。
一、本域和子域的互動:www.s135.com 和 blog.s135.com
二、本域和其他域的互動:blog.s135.com 和 api.bz
本域和子域的互動,可以通過iframe設定兩個網域名稱document.domain = "s135.com",實現統一s135.com域下的跨域訪問。
本域和其他域的互動,可以通過iframe、代理、JS建立動態指令碼等幾種方法來實現,這裡有篇文章對幾種方法作了簡要的介紹。
iframe、JS建立動態指令碼這兩種方法,需要開發人員能控制兩個域,兩端都要編寫相應的代碼,非常麻煩。在本網域服務器上用PHP寫個代理中轉程式,讓本域PHP程式去讀取遠程其他域的資料再返回給自己,是常用的方法。但是,在本域“前端是CDN或Squid快取服務器,後端才是PHP應用程式伺服器”的系統架構下,穿透CDN或Squid去訪問不能被緩衝的PHP代理中轉程式,效率是很低的。
國外有人嘗試用 Flash 做 JavaScript 和 AJAX 跨域訪問中轉,無疑是一個好方法。JavaScript 將資料提交給本域下的 Flash,通過 Flash 中轉去訪問其他域的介面,條件只需要其他域的根目錄下有一個crossdomain.xml檔案,檔案中設定允許所有網域名稱或允許本域訪問即可。很多網站的API網域名稱都提供了crossdomain.xml檔案。
例如:
1、新浪部落格的crossdomain.xml檔案(http://blog.sina.com.cn/crossdomain.xml)設定了允許所有網域名稱訪問;
2、飯否API的crossdomain.xml檔案(http://api.fanfou.com/crossdomain.xml)設定了允許所有網域名稱訪問;
3、校內網API的crossdomain.xml檔案(http://api.xiaonei.com/crossdomain.xml)設定了允許所有網域名稱訪問;
4、優酷網的crossdomain.xml檔案(http://www.youku.com/crossdomain.xml)設定了允許所有網域名稱訪問;
5、馬鈴薯網的crossdomain.xml檔案(http://www.tudou.com/crossdomain.xml)設定了允許所有網域名稱訪問;
6、逍遙視頻的crossdomain.xml檔案(http://v.xoyo.com/crossdomain.xml)設定了只允許*.xoyo.com網域名稱訪問;
7、網易的crossdomain.xml檔案(http://www.163.com/crossdomain.xml)設定了只允許tech.163.com、sports.163.com等幾個網域名稱訪問。
本人在“Cross-domain AJAX using Flash”的基礎上,增加了對錶單進行智能處理的功能,封裝了一個JavaScript包:AJAXCDR。通過 AJAXCDR,即可輕鬆地解決 JavaScript 和 AJAX 跨域 HTTP POST/GET 表單請求,支援IE、Firefox、GoogleChrome等多種瀏覽器。
AJAXCDR 擁有兩個檔案:ajaxcdr.js 和 ajaxcdr.swf,AJAXCDR 擁有一個 JavaScript 函數 AjaxCrossDomainRequest() 和一個全域變數 AjaxCrossDomainResponse。
一、AJAXCDR 下載:
http://blog.s135.com/demo/ajaxcdr/ajaxcdr-1.0.zip
下載檔案 點擊這裡下載檔案
注意:請編輯ajaxcdr.js,尋找“/demo/ajaxcdr/ajaxcdr.swf”,將這段Flash檔案路徑換成您的路徑。
二、AJAXCDR 函數說明:
1、JavaScript函數:
AjaxCrossDomainRequest(URL, Method, FormName, CallBack);
參數說明:
URL:需要訪問的URL地址,相當於表單的action=的值。
Method:方法,本函數支援POST和GET方法,相當於表單的method=的值。
FormName:表單名稱,相當於表單的name=的值。
CallBack:回呼函數,請求完成後,回調使用者的一個函數,使用者可以在該函數內對傳回值進行處理。
2、JavaScript全域變數:
AjaxCrossDomainResponse
當使用者調用AjaxCrossDomainRequest()函數完成 HTTP POST/GET 請求後,該函數會把伺服器端返回的資料寫入到AjaxCrossDomainResponse變數中,您可以通過AjaxCrossDomainResponse變數擷取傳回值。
三、AJAXCDR 應用執行個體:
1、執行個體一(簡單示範):
示範地址: http://blog.s135.com/demo/ajaxcdr/demo1.htmlview plaincopy to clipboardprint?
- <form name="cross_domain_demo">
- <input name="title" type="text" value="測試資料">
- </form>
-
- <a href="javascript:AjaxCrossDomainRequest('http://api.bz/ajaxcdr/echo.php', 'POST', 'cross_domain_demo', 'mycallback()');">提交</a>
-
- <script type="text/javascript">
- function mycallback(){
- alert(AjaxCrossDomainResponse);
- }
- </script>
-
- <script type="text/javascript" src="/demo/ajaxcdr/ajaxcdr.js"></script>
<form name="cross_domain_demo"><br /><input name="title" type="text" value="測試資料"><br /></form><br /><a href="javascript:AjaxCrossDomainRequest('http://api.bz/ajaxcdr/echo.php', 'POST', 'cross_domain_demo', 'mycallback()');">提交</a><br /><script type="text/javascript"><br />function mycallback(){<br /> alert(AjaxCrossDomainResponse);<br />}<br /></script><br /><script type="text/javascript" src="/demo/ajaxcdr/ajaxcdr.js"></script> echo.php 原始碼為:http://api.bz/ajaxcdr/echo.txt
crossdomain.xml 檔案為:http://api.bz/crossdomain.xml
2、執行個體二(複雜表單示範):
示範地址: http://blog.s135.com/demo/ajaxcdr/demo2.html
<html><head><title>Ajax 跨域 HTTP POST/GET 訪問請求示範:Ajax Cross Domain HTTP POST/GET Request Demo</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><style type="text/css"><!--body,td,th { font-size: 14px;}--></style></head><body><form name="cross_domain_demo"><table width="600" border="1"> <tr> <td colspan="2" align="center" valign="top"><strong>Ajax 跨域 HTTP POST/GET 訪問請求示範(滑鼠右鍵查看HTML原始碼)</strong></td> </tr> <tr> <td colspan="2" align="center" valign="top">函數說明與:<a href="http://blog.s135.com/ajaxcdr/" target="_blank">http://blog.s135.com/ajaxcdr/</a></td> </tr> <tr> <td align="right" valign="top">username</td> <td><input name="title" type="text" value="使用者名稱"></td> </tr> <tr> <td align="right" valign="top">password</td> <td><input name="password" type="password" value="123456"></td> </tr> <tr> <td align="right" valign="top">content</td> <td><textarea name="content" cols="58" rows="5">文本地區值</textarea></td> </tr> <tr> <td align="right" valign="top">city</td> <td> <select name="city"> <option value="北京">北京</option> <option value="上海">上海</option> <option value="深圳">深圳</option> </select> </td> </tr> <tr> <td align="right" valign="top">interest</td> <td> <select name="interest[]" multiple> <option value="玩遊戲">玩遊戲</option> <option value="踢足球">踢足球</option> <option value="看書">看書</option> <option value="旅遊">旅遊</option> </select> </td> </tr> <tr> <td align="right" valign="top">gender</td> <td> <input type="radio" name="gender" value="男">男 <input type="radio" name="gender" value="女" >女 <input type="radio" name="gender" value="未知" checked>未知 </td> </tr> <tr> <td align="right" valign="top">grade</td> <td> <input type="checkbox" name="grade[]" value="等級一">等級一 <input type="checkbox" name="grade[]" value="等級二">等級二 <input type="checkbox" name="grade[]" value="等級三">等級三 <input type="checkbox" name="grade[]" value="等級四">等級四 </td> </tr> <tr> <td align="right" valign="top">publish</td> <td><input type="checkbox" name="publish" value="發布">發布</td> </tr> <tr> <td align="right" valign="top"> </td> <td> <a href="javascript:AjaxCrossDomainRequest('http://api.bz/ajaxcdr/echo.php', 'POST', 'cross_domain_demo', 'mycallback(\'參數①\', \'參數②\', myparam)');"><img src="post_button.gif" width="100" height="24" align="absmiddle" border="0"></a> <button onClick="AjaxCrossDomainRequest('http://api.bz/ajaxcdr/echo.php', 'GET', 'cross_domain_demo', 'mycallback(\'參數①\', \'參數②\', myparam)'); return false;">GET方式提交</button> </td> </tr> </table></form><table width="600" border="1"> <tr> <td>JavaScript POST/GET 跨域提交資訊到:http://api.bz/ajaxcdr/echo.php (<a href="http://api.bz/ajaxcdr/echo.txt" target="_blank">原始碼</a>) </td> </tr> <tr> <td><strong>api.bz伺服器端返回資訊:</strong></td> </tr> <tr> <td><div id="return_info"></div> </td> </tr></table><script type="text/javascript">var myparam = "參數③";function mycallback(param1, param2, param3){ //提示:AjaxCrossDomainResponse是一個全域變數,它的值為遠程伺服器的傳回值。 document.getElementById('return_info').innerHTML = "<pre>" + param1 + param2 + param3 + "<BR>" + AjaxCrossDomainResponse + "</pre>";}</script><script type="text/javascript" src="/demo/ajaxcdr/ajaxcdr.js"></script></body></html>
echo.php 原始碼為:http://api.bz/ajaxcdr/echo.txt
crossdomain.xml 檔案為:http://api.bz/crossdomain.xml
楊過後記:張晏同學給我們帶來了這麼好的文章,白拿也不好意思,最後奉獻一個aspx的demo吧,見http://files.cnblogs.com/yjmyzz/ajaxcdr_aspx_demo.7z