日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

AJAX跨域访问解决方案

發布時間:2023/11/27 生活经验 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AJAX跨域访问解决方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Case I. Web代理的方式 (on Server A)

?????? 即用戶訪問A網站時所產生的對B網站的跨域訪問請求均提交到A網站的指定頁面,由該頁面代替用戶頁面完成交互,從而返回合適的結果。此方案可以解決現階段所能夠想到的多數跨域訪問問題,但要求A網站提供Web代理的支持,因此A網站與B網站之間必須是緊密協作的,且每次交互過程,A網站的服務器負擔增加,且無法代用戶保存session狀態。

Case II. on-Demand方式 (on Server A)

???????? MYMSN的門戶就用的這種方式,不過 MYMSN中不涉及跨域訪問問題。在頁面內動態生成新的<script>,將其src屬性指向別的網站的網址,這個網址返回的內容必須是合法的Javascript腳本,常用的是JSON消息。此方案存在的缺陷是, script的src屬性完成該調用時采取的方式時get方式,如果請求時傳遞的字符串過大時,可能會無法正常運行。不過此方案非常適合聚合類門戶使用。

   1: <html>
   2: <head>
   3: <script>
   1:? 
 
   2: function loadContent()
 
   3: {
 
   4: var s=document.createElement('SCRIPT');
 
   5: s.src='http://www.anotherdomain.com/TestCrossJS.aspx?f=setDivContent';
 
   6: document.body.appendChild(s);
 
   7: }
 
   8: function setDivContent(v)
 
   9: {
 
  10: var dv = document.getElementById("dv");
 
  11: dv.innerHTML = v;
 
  12: }
</script>
   4: </head>
   5: <body>
   6: <div></div>
   7:? 
   8: <input value="Click Me">
   9: </body>
  10: </html>
  11: //其中的www.anotherdomain.com/TestCrossJS.aspx是這樣的,
  12: <script runat="server">
   1:? 
 
   2: void Page_Load(object sender, EventArgs e)
 
   3: {
 
   4:   string f = Request.QueryString["f"];
 
   5:   Response.Clear();
 
   6:   Response.ContentType = "application/x-javascript";
 
   7:   Response.Write(String.Format(@"
 
   8:                    {0}('{1}');", 
 
   9:                    f,
 
  10:                    DateTime.Now));
 
  11:   Response.End();
 
  12: }
</script>

點擊“Click Me”按鈕,生成一個新的script tag,下載對應的 Javascript 腳本,結束時回調其中的setDivContent(),從而更新網頁上一個div的內容。

Case III. iframe方式 (on Server A)

?????? 查看過醒來在javaeye上的一篇關于跨域訪問的帖子,他提到自己已經用iframe的方式解決了跨域訪問問題。數據提交跟獲取,采用iframe這種方式的確可以了,但由于父窗口與子窗口之間不能交互(跨域訪問的情況下,這種交互被拒絕),因此無法完成對父窗口效果的影響。

在頁面內嵌或動態生成指向別的網站的IFRAME,然后這2個網頁間可以通過改變對方的anchor hash fragment來傳輸消息。改變一個網頁的anchor hash fragment并不會使瀏覽器重新裝載網頁,所以一個網頁的狀態得以保持,而網頁本身則可以通過一個計時器(timer)來察覺自己anchor hash的變化,從而相應改變自己的狀態。

1. http://domain1/TestCross.html:

   1: <html>
   2: <head>
   3: <script>
   1:? 
 
   2: var url = "http://domain2/TestCross.html"
 
   3: var oldHash = null;
 
   4: var timer = null;
 
   5:? 
 
   6: function getHash()
 
   7: {
 
   8: var hash = window.location.hash;
 
   9: if ((hash.length >= 1) && (hash.charAt(0) == '#'))
 
  10: {
 
  11: hash = hash.substring(1);
 
  12: }
 
  13:? 
 
  14: return hash;
 
  15: }
 
  16: function sendRequest()
 
  17: {
 
  18: var d = document;
 
  19: var t = d.getElementById('request');
 
  20: var f = d.getElementById('alienFrame');
 
  21: f.src = url + "#" + t.value + "<br/>" + new Date();
 
  22: }
 
  23:? 
 
  24: function setDivHtml(v)
 
  25: {
 
  26: var d = document;
 
  27: var dv = d.getElementById('response');
 
  28: dv.innerHTML = v;
 
  29: }
 
  30:? 
 
  31: function idle()
 
  32: {
 
  33: var newHash = getHash();
 
  34:? 
 
  35: if (newHash != oldHash)
 
  36: {
 
  37: setDivHtml(newHash);
 
  38: oldHash = newHash;
 
  39: }
 
  40:? 
 
  41: timer = window.setTimeout(idle, 100);
 
  42: }
 
  43: function window.onload()
 
  44: {
 
  45: timer = window.setTimeout(idle, 100);
 
  46: }
</script>
   4: </head>
   5: <body>

請求:<input> <input value="發送" /><br/>
回復:<div></div>

<iframe src="http://domain2/TestCross.html"></iframe>

</body>
</html>

2. http://domain2/TestCross.html:

   1: <html>
   2: <head>
   3: <script>
   1:? 
 
   2: var url = "http://domain1/TestCross.html"
 
   3: var oldHash = null;
 
   4: var timer = null;
 
   5:? 
 
   6: function getHash()
 
   7: {
 
   8: var hash = window.location.hash;
 
   9: if ((hash.length >= 1) && (hash.charAt(0) == '#'))
 
  10: {
 
  11: hash = hash.substring(1);
 
  12: }
 
  13:? 
 
  14: return hash;
 
  15: }
 
  16: function sendRequest()
 
  17: {
 
  18: var d = document;
 
  19: var t = d.getElementById('request');
 
  20: var f = parent;
 
  21: //alert(f.document); //試著去掉這個注釋,你會得到“Access is denied”
 
  22: f.location.href = url + "#" + t.value + "<br/>" + new Date();
 
  23: }
 
  24:? 
 
  25: function setDivHtml(v)
 
  26: {
 
  27: var d = document;
 
  28: var dv = d.getElementById('response');
 
  29: dv.innerHTML = v;
 
  30: }
 
  31:? 
 
  32: function idle()
 
  33: {
 
  34: var newHash = getHash();
 
  35:? 
 
  36: if (newHash != oldHash)
 
  37: {
 
  38: setDivHtml(newHash);
 
  39: oldHash = newHash;
 
  40: }
 
  41:? 
 
  42: timer = window.setTimeout(idle, 100);
 
  43: }
 
  44:? 
 
  45: function window.onload()
 
  46: {
 
  47: timer = window.setTimeout(idle, 100);
 
  48: }
</script>
   4: </head>
   5: <body>

請求:<input> <input value="發送" /><br/>
回復:<div></div>

</body>
</html>

?????? 兩個網頁基本相同,第一個網頁內嵌一個IFRAME,在點擊“發送”按鈕后,會將文本框里的內容通過hash fragment傳給IFRAME。點擊IFRAME里的“發送”按鈕后,它會將文本框里的內容通過hash fragment傳給父窗口。因為是只改動了hash fragment,瀏覽器不會重新load網頁內容,這里使用了一個計時器來檢測URL變化,如果變化了,就更新其中一個div的內容 。

Case IV. 用戶本地轉儲方式 (local)

IE本身依附于windows平臺的特性為我們提供了一種基于iframe,利用內存來“繞行”的方案,即兩個window之間可以在客戶端通過windows剪貼板的方式進行數據傳輸,只需要在接受數據的一方設置Interval進行輪詢,獲得結果后清除Interval即可。FF的平臺獨立性決定了它不支持剪貼板這種方式,而以往版本的FF中存在的插件漏洞又被fixed了,所以FF無法通過內存來完成暗渡陳倉。而由于文件操作FF 也沒有提供支持(無法通過Cookie跨域完成數據傳遞),致使這種技巧性的方式只能在IE中使用。

Case V: (其實還是在服務端A用iframe解決了與服務器B通信的問題)

要解決的問題:發生在用戶提交網頁 URL (還包括 Tag, Notes 等)給 Bookmark 服務器時。

關于 URL 的提交至少可以有三種方式:

1.?????? 登陸 Bookmark 服務器的提交頁面,將要收藏的 URL 通過該頁面提交給服務器。

2.?????? 安裝瀏覽器插件,通過插件將 URL 提交給服務器。

3.?????? 從 Bookmark 服務器動態加載 javascript 小工具到當前頁面,通過它來完成提交工作。

??? 第一種方式開發起來最簡單,但對用戶來講比較麻煩,每次都需要先登陸 Bookmark 服務器才能完成提交;第二種方式我并不熟悉插件開發,而且用戶也不喜歡太多的插件堆滿自己的瀏覽器;第三種方式開發難度小,又避免了每次登陸服務器的麻煩,所以最終采用它。第三種方式中動態加載的 javascript 小工具除了需要生成 UI 供用戶填寫信息( URL , tag , notes 等),當用戶點擊提交的時候,還要完成與服務器通信的功能。

???? 跨域訪問,簡單來說就是 A 網站的 javascript 代碼試圖訪問 B 網站,包括提交內容和獲取內容。由于安全原因,跨域訪問是被各大瀏覽器所默認禁止的。寫過跨域訪問 ajax 的朋友相信都遇到過被告知“沒有權限”的情況。通過 XMLHttp 來發送數據給 Bookmark 服務器的嘗試失敗了。于是,看到網上的一些資料,我又開始嘗試用 javascript 小工具在用戶網頁動態創建一個隱藏的 iframe, iframe 的 src 指向服務器的一個 servlet ,試圖通過調用 iframe 中提供的 javascript 來完成與服務器的通信。但不幸的是,用戶網頁中的 javascript 代碼訪問 iframe 也被瀏覽器歸為跨域訪問(特指 iframe 的 src 指向其它網站的情形),嘗試再次失敗。

最終,在一篇文章中看到,與 iframe 不同,如果 A 網站從 B 網站加載 javascript , A 網站可以自由的訪問該 javascript 的內容,并不會被瀏覽器認為是跨域訪問。模仿剛才 iframe 的思路,當用戶點擊提交時,可以動態創建一個 javascript 對象,該對象的 src 指向 Bookmark 服務器的一個 servlet ,注意: URL 、 Tag 、 Notes 、 User 、Password 等信息被作為 src URL 參數傳給服務器。請看下面的代碼:

?

   1: var url = "http://localhost:8080/Deeryard/BookmarkServlet?" +
   2:? 
   3: "url=" + url_source + "&" + "title=" + title + "&" +
   4:? 
   5: "tag=" + tag + "&" + "notes=" + notes + "&" + "user=" + user + "&" + "password=" + password;
   6:? 
   7: url = encodeURI(url);
   8:? 
   9: //Submit to server with a trick
  10:? 
  11: var js_obj = document.createElement( "script" );
  12:? 
  13: js_obj.type = "text/javascript" ;
  14:? 
  15: js_obj.setAttribute( "src" , url);
  16:? 
  17: //Get response from server by appending it to document
  18:? 
  19: document.body.appendChild(js_obj);
  20:? 

??????? 上面例子中, js_obj.setArrribute() 將信息作為 src 的 URL 參數提交給了 Bookmark servlet 。那么用戶又如何取得服務器的響應信息呢?答案就是最末一行代碼, servlet 的輸出必須是 javascript 代碼,它可以調用用戶網頁上的其他 javascript 函數,以及操作 dom 對象。下面的 servlet 代碼生成了一個 javascript 函數調用:

out.write("onServerResponse(INADEQUATE_INFORMATION);");

document.body.appendChild(js_obj) 執行后 onServerResponse( INADEQUATE_INFORMATION) 就會得到執行,使客戶網頁響應服務器結果。這樣一個完整的通信過程就完成了。

CaseVI:Tomcat + PHP + HTML(含JS)(on Server A)

服務器A上已經裝好了Tomcat, 我們寫一個test.html(含JS),再寫一個PHP文件(由其來完成跨域通信要求)。

轉載于:https://www.cnblogs.com/sunBolg/archive/2012/09/13/2683914.html

總結

以上是生活随笔為你收集整理的AJAX跨域访问解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。