解決跨域訪問
『壹』 訪問本地頁面 怎麼解決瀏覽器跨域問題
前幾天,工作上有一新需求,需要前端web頁面非同步調用後台的Webservice方法返回信息。實現方法有多種,本例採用jQuery+Ajax,完成後,在本地調試了一切ok,但是部署到伺服器上以後就出現問題了,後台服務調用沒有響應,怎麼回事?代碼沒怎麼改動,唯一修改的地方就是jQuery的ajax方法中的url地址。難道是這里的問題,經過檢查和調試,發現原來是同源策略在作怪,我們知道,javaScript或jQuery是在Web前端開發中經常使用的動態腳本技術。在JavaScript中,有一個很重要的安全性限制,被稱為「Same- Origin Policy」(同源策略)。這一策略對於JavaScript代碼能夠訪問的頁面內容做了很重要的限制,即JavaScript只能訪問與包含它的文檔或腳本 在同一域名下的內容。不同域名下的腳本不能互相訪問,即便是子域也不行。 但是有時候又不可避免地需要進行跨域操作,這時候「同源策略」就是一個限制了,怎麼辦呢?採用JSONP跨域GET請求是一個常用的解決方案,下面我們來看一下JSONP跨域是如何實現的,並探討下JSONP跨域的原理。 這里提到了JSONP,那有人就問了,它同JSON有什麼區別不同和區別呢,接下我們就來看看,網路有以下說明: JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。它基於JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一個子集。 JSON採用完全獨立於語言的文本格式,但是也使用了類似於C語言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。這些特性使JSON成為理想的數據交換語言。易於人閱讀和編寫,同時也易於機器解析和生成(網路傳輸速度快)。 JSONP(JSON with Padding)是JSON的 一種「使用模式」,可用於解決主流瀏覽器的跨域數據訪問的問題。由於同源策略,一般來說位於 server1 的網頁無法與不是 server1的伺服器溝通,而 HTML 的<script> 元素是一個例外。利用 <script> 元素的這個開放策略,網頁可以得到從其他來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並不是 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。 到這里,應該明白了,JSON是一種輕量級的數據交換格式,像xml一樣,是用來描述數據間的。JSONP是一種使用JSON數據的方式,返回的不是JSON對象,是包含JSON對象的javaScript腳本。 那JSONP是如何工作的呢,我們知道,由於同源策略的限制,XmlHttpRequest只允許請求當前源(域名、協議、埠)的資源。若要跨域請求出於安全性考慮是不行的,但是我們發現,Web頁面上調用js文件時則不受是否跨域的影響,而且擁有」src」這個屬性的標簽都擁有跨域的能力,比如<script>、<img>、<iframe>,這時候,聰明的程序猿就想到了變通的方法,如果要進行跨域請求, 通過使用html的script標記來進行跨域請求,並在響應中返回要執行的script代碼,其中可以直接使用JSON傳遞 javascript對象。即在跨域的服務端生成JSON數據,然後包裝成script腳本回傳,這不就突破同源策略的限制,解決了跨域訪問的問題了么。 下面我們就看下怎麼實現: 前端代碼: function CallWebServiceByJsonp() { $("#SubEquipmentDetails").html(''); $.ajax({ type: "GET", cache: false, url: "servername/webservice/webservice.asmx/GetSingleInfo", data: { strCparent: $("#Equipment_ID").val() }, dataType: "jsonp", //jsonp: "callback", jsonpCallback: "OnGetMemberSuccessByjsonp" }); } function OnGetMemberSuccessByjsonp(data) { //處理data alert(data); } 後端的WebService代碼: [WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)] public void GetSingleInfo(string strCparent) { string ret = string.Empty; HttpContext.Current.Response.ContentType = "application/json;charset=utf-8"; string jsonCallBackFunName = HttpContext.Current.Request.Params["callback"].ToString(); //string jsonCallBackFunName1 = HttpContext.Current.Request.QueryString["callback"].Trim(); //上面代碼必須 //中間代碼執行自己的業務操作,可返回自己的任意信息(多數據類型) BLL.equipment eq_bll = new BLL.equipment(); List<Model.equipment> equipmentList = new List<Model.equipment>(); equipmentList = eq_bll.GetModelEquimentList(strCparent); ret = JsonConvert.SerializeObject(equipmentList); //下面代碼必須 HttpContext.Current.Response.Write(string.Format("{0}({1})", jsonCallBackFunName, ret)); HttpContext.Current.Response.End(); } 如上所示,前端的CallWebServiceByJsonp方法採用jQuery的ajax方法調用後端的Web服務GetSingleInfo方法,後台的GetSingleInfo方法,使用前端的回調方法OnGetMemberSuccessByjsonp包裝後台的業務操作的JSON對象,返回給前端一段javascript片段執行。巧妙的解決了跨域訪問問題。 JSONP的缺點: JSONP不提供錯誤處理。如果動態插入的代碼正常運行,你可以得到返回,但是如果失敗了,那麼什麼都不會發生。 以上內容簡單給大家介紹了JSONP解決Ajax跨域訪問問題的思路,希望能夠幫助到大家,如果大家有疑問歡迎給我留言,小編會及時回復大家的,在此也非常感謝大家對腳本之家網站的支持!
『貳』 前端跨域方式有哪些
處理跨域方法一——JSONP
1.JSONP原理
利用script元素的這個開放策略,網頁可以得到從其他來源動態產生的 JSON 數據。JSONP請求一定需要對方的伺服器做支持才可以。
2.JSONP和AJAX對比
JSONP和AJAX相同,都是客戶端向伺服器端發送請求,從伺服器端獲取數據的方式。但AJAX屬於同源策略,JSONP屬於非同源策略(跨域請求)
3.JSONP優缺點
JSONP優點是兼容性好,可用於解決主流瀏覽器的跨域數據訪問的問題。缺點是僅支持get方法具有局限性。
4.JSONP的流程(以第三方API地址為例,不必考慮後台程序)
聲明一個回調函數,其函數名(如fn)當做參數值,要傳遞給跨域請求數據的伺服器,函數形參為要獲取目標數據(伺服器返回的data)。
創建一個
伺服器接收到請求後,需要進行特殊的處理:把傳遞進來的函數名和它需要給你的數據拼接成一個字元串,例如:傳遞進去的函數名是fn,它准備好的數據是fn([{「name」:「jianshu」}])。
最後伺服器把准備的數據通過HTTP協議返回給客戶端,客戶端再調用執行之前聲明的回調函數(fn),對返回的數據進行操作。
處理跨域方法二——CORS
1.CORS原理
整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與。對於開發者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感覺。因此,實現CORS通信的關鍵是伺服器。只要伺服器實現了CORS介面,就可以跨源通信。
2.CORS優缺點
CORS要求瀏覽器(>IE10)和伺服器的同時支持,是跨域的根本解決方法,由瀏覽器自動完成。
優點在於功能更加強大支持各種HTTP Method,缺點是兼容性不如JSONP。
處理跨域方法三——WebSocket
Websocket是HTML5的一個持久化的協議,它實現了瀏覽器與伺服器的全雙工通信,同時也是跨域的一種解決方案。WebSocket和HTTP都是應用層協議,都基於 TCP 協議。但是 WebSocket 是一種雙向通信協議,在建立連接之後,WebSocket 的 server 與 client 都能主動向對方發送或接收數據。同時,WebSocket 在建立連接時需要藉助 HTTP 協議,連接建立好了之後 client 與 server 之間的雙向通信就與 HTTP 無關了。
原生WebSocket API使用起來不太方便,我們使用Socket.io,它很好地封裝了webSocket介面,提供了更簡單、靈活的介面,也對不支持webSocket的瀏覽器提供了向下兼容。
處理跨域方法四——postMessage
如果兩個網頁不同源,就無法拿到對方的DOM。典型的例子是iframe窗口和window.open方法打開的窗口,它們與父窗口無法通信。HTML5為了解決這個問題,引入了一個全新的API:跨文檔通信 API(Cross-document messaging)。這個API為window對象新增了一個window.postMessage方法,允許跨窗口通信,不論這兩個窗口是否同源。postMessage方法的第一個參數是具體的信息內容,第二個參數是接收消息的窗口的源(origin),即"協議 + 域名 + 埠"。也可以設為*,表示不限制域名,向所有窗口發送。
『叄』 is 跨域處理方式
1、通過後端代理的方式。即前端訪問的域名不變,根據域名後的資源路徑由後端伺服器進行訪問獲取數據後再返回給前端。
2、jsonp的方式,這個我個人比較推薦,尤其是一些對外開放的數據。但是主要應用於get請求,其他請求方式不起效果。
3、跨域資源共享。Java後端的話可以在RequstMapping括弧請求路徑上添加@CrossOrigin這個方式去實現允許介面跨域訪問,通過返回請求頭。這樣就可以is跨域處理方式。
『肆』 怎麼解決伺服器間的跨域問題
服務端的解決方案的基本原理就是,由客戶端將請求發給本域伺服器,再由本域伺服器的代理來請求數據並將響應返回給客戶端。
最常用的伺服器解決方案就是利用web伺服器本身提供的proxy功能,如apache和lighttpd的mod_proxy模塊。在網路內
部,transmit的分流功能也可以解決部分跨域問題。但這些方法都有一定的局限性,鑒於安全性等問題的考慮,space這邊最後開發了一個專門用於處
理跨域請求代理服務的spproxy模塊,用於徹底解決js跨域問題。
下面我們將以空間的開放平台為例,簡單介紹下如何通過apache的mod_proxy、transmit的分流以及space的spproxy模塊來解
決該跨域問題,並簡單介紹下spproxy的一些特性、缺點及下一步的改進計劃。
空間在展現每個UWA開放模塊之前都必須請求該模塊的xml源代碼以進行解析,每個模塊的源代碼文件都是存放在act域下的/ow/uwa目錄下,那麼在
用戶空間首頁(hi域)中請求該xml文件時就會存在js跨域問題。要解決該問題,只能讓js向hi域的web伺服器請求xml文件,而hi域web服務
器則通過一定的代理機制(如mod_proxy、transmit分流、spproxy)向act域的web伺服器請求文件
『伍』 什麼是跨域如何解決跨域問題
什麼是跨域?
跨域,指的是瀏覽器不能執行其他網站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對JavaScript施加的安全限制
解決辦法:
1、JSONP:
使用方式就不贅述了,但是要注意JSONP只支持GET請求,不支持POST請求。
2、代理:
例如www.123.com/index.html需要調用www.456.com/server.php,可以寫一個介面www.123.com/server.php,由這個介面在後端去調用www.456.com/server.php並拿到返回值,然後再返回給index.html,這就是一個代理的模式。相當於繞過了瀏覽器端,自然就不存在跨域問題。
3、PHP端修改header(XHR2方式)
在php介面腳本中加入以下兩句即可:
header('Access-Control-Allow-Origin:*');//允許所有來源訪問
header('Access-Control-Allow-Method:POST,GET');//允許訪問的方式
『陸』 如何配置解決跨域的問題
方法/步驟
伺服器端對於CORS的支持,是通過設置Access-Control-Allow-Origin來進行的。如果瀏覽器檢測到相應的設置,就可以允許Ajax進行跨域的訪問
打開控制面板,選擇管理工具
選擇iis
右鍵單擊自己的網站,選擇瀏覽
打開網站所在目錄
用記事本打開web.config文件添加如圖的一句話,保存,重啟網站就好了,客戶端直接用html5編輯,不用任何設置
『柒』 如何解決IE瀏覽器跨域問題
工具:
IE瀏覽器
方法如下:
1、打開IE瀏覽器,在工具菜單下選擇Internet選項,打開Internet選項卡
2、切換到安全選項卡下,點擊可信站點,然後單擊站點按鈕
3、可信站點窗口輸入網址到可信站點的區域,點擊添加按鈕,網址則會添加到網站列表下,最後關閉可信站點窗口
4、還是在安全選項卡下的可信站點,點擊自定義級別
5、打開站點區域窗口,找到跨域瀏覽窗口和框架選擇啟用
6、在當前窗口中繼續往下翻,通過域訪問數據源也選擇啟用,點擊確定關閉受信任的站點區域窗口
7、在Internet窗口也點擊確定按鈕,同時關閉瀏覽器
8、在請求的js腳本中添加是否允許跨域訪問的許可權,jQuery.support.cors默認值為true,則代表允許;反之,不允許。設置完成,重新打開瀏覽器驗證即可。
『捌』 如何解決前端跨域問題
可以使用伺服器代理或者在後端設置允許跨域。
現在的項目一般是在後端設置允許跨域,前端在帶有允許跨域的情況下,可以像沒有跨域一樣正常訪問。
如果前端單獨發布到伺服器,也可以在伺服器是設置代理,使用代理轉發請求。
『玖』 如何解決跨域問題
關於跨域名問題還是問題么,這方面的解決實踐非常多,今天我就舊話重提把我所知道的通過幾個應用場景來分別總結一下(轉帖請註明出處:http://blog.csdn.net/lenel)
先說明一點:我說的某某域名在您的控制下的意思是這個域名下的網頁由您來負責開發內部的JavaScript
場景一:將bbs.xxx.com的頁面用iframe嵌入到www.xxx.com的中,如何在iframe內外使用js通信(轉帖請註明出處:http://blog.csdn.net/lenel)
一級域名都是xxx.com 這個域名一定是在您的控制下,所以你只要在兩個頁面中同時升級域名即可
在父窗口和iframe內部分別加上js語句:document.domain="xxx.com";
之後2個頁面就等於在同一域名下,通過window.parent oIframe.contentDocument就可以相互訪問,進行無障礙的JS通信
在新浪、淘寶等很多頁面都能找到這樣的語句。不過document.domain不可以隨便指定,只能向上升級,從bbs.xxx.com升級到yyy.com肯定會出錯
場景二:將www.yyy.com的頁面用iframe嵌入到www.xxx.com的中,兩個域名都在您的控制下,如何在iframe內外進行一定的數據交流(轉帖請註明出處:http://blog.csdn.net/lenel)
你可以通過相互改變hash值的方式來進行一些數據的通信
這里的實現基於如下技術要點:
1、父窗口通過改變子窗口的src中的hash值把一部分信息傳入,如果src只有hash部分改變,那麼子窗口是不會重新載入的。
2、
子窗口可以重寫父窗口的location.href,但是注意這里子窗口無法讀取而只能重寫location.href所以要求前提是您控制兩個域名,知
道當前父窗口的location.href是什麼並寫在子窗口內,這樣通過parent.location.href =
"已知的父窗口的href"+"#"+hash。這樣父窗口只有hash改變也不會重載。
3、上面兩步分別做到了兩個窗口之間的無刷新數據通知,
那麼下面的來說如何感知數據變化。標准中沒有相關規定,所以當前的任意瀏覽器遇到location.hash變化都不會觸發任何javaScript事
件,也就是說您要自己寫監聽函數來監視loaction.hash的值的變化。做法是通過setTimeout或者setInterval來寫一個監聽函
數每20-100ms查看一下hash是否變化,如果變化了驅動js根據新的數據做想做的事情。
這種實現的一些分析:
1、信息通道是雙向的,當然會兼容單向,如果只是父窗口向子窗口通知數據,只需要子窗口寫hash監聽,反之亦然。
2、局限性也是頗大,因為這種通信的前提是雙方知道對方的location.href。如果父窗口帶有動態的location.search也就是查詢參數,那麼子窗口的處理上就比較困難,需要把父窗口的location.search作為傳遞信息的一部分告知子窗口。
3、另外的困擾會有瀏覽器帶給你,IE之外的瀏覽器遇到hash的改變會記錄歷史,這樣你在處理前進後退的時候會非常頭疼
場景三:將www.yyy.com的頁面用iframe嵌入到www.xxx.com的中,只有被嵌入的yyy.com在您的控制下,如何在iframe內外進行一定的交流
真實場景:google adsence的一個需求,你希望google發現您的頁面不能匹配出相關性非常好的按點擊付費廣告時,你希望google的廣告iframe能夠隱藏。
google的廣告iframe在google域下顯然不能把自己隱藏掉,那麼怎麼辦呢?
1、google會提供給你一個html頁面
2、您將這個頁面放置在您的域名下,並告訴google它的位置
3、當google發現沒有很好的廣告時,會將子窗口的loaction重定向到您的那個頁面下,這樣您的頁面因為同域名就可以訪問父頁面來隱藏自己了
是不是很巧的方法?
場景四:您是內容發布商,如何改造介面,讓其他域名下的頁面可以從瀏覽器端出發獲得您的數據
我們知道ajax的xmlHttpRequest()說到底是一個無刷新請求伺服器數據的輔助工具,但是xmlHttpRequest並不能跨域名請求數據,在某些情況下成了極大的限制。
但是我們如果通過其他方式完成無刷新請求數據不也可以么,我們用Dom方法操作動態JS腳本請求來做這件事。
//創建一個腳本節點
var oScript = document.createElement('script');
//指定腳本src src可以指向任意域名
//注意src不再指向靜態js,而是帶著查詢參數指向一個動態腳本廣播服務。
oScript.src = "http://yyy.com/query.php?"+yourQueryString;
//如果指定了charset 同時還可以解決xmlHttpRequest另一大困擾 亂碼問題
//oScript.charset = "utf-8";
//通過Dom操作把這個新的節點加入到文檔當中
document.getElementsByTagName("head")[0].appendChild(oScript);
這樣只要query.php的輸出是可執行的javaScript腳本,比如:djsCallBack({jsondata});
當他從伺服器返回後就會自動執行,你可以方便的用json方式來做數據傳遞了。
要注意,您的腳本請求最好帶上時間戳,避免瀏覽器緩存造成取回數據實時性下降。
如果您是數據提供者,您可以要求數據索取者在查詢參數中提供回調函數名,比如query.php?callback=myDataHandler&key=...?
這樣您就可以根據參數來提供給他myDataHandler({jsondata}),這樣不同的數據索取者都會得到自定義的正確的非同步回調。
進一步發展,可以做一個統一的從xml到動態json的數據轉化伺服器,脫離數據的實際意義,針對任何xml介面都可以作為轉化後提供給客戶端直接訪問。
這樣就不用針對單獨xml數據服務,為了跨域名而做各自的後台數據抓取轉化服務。
用動態腳本傳數據功能非常強大,去年我最先在YAHOO的站點上看到這樣的應用,讓人眼前一亮。
總結總結:
第一種場景,相應的處理辦法有這非常好的效果,可以說完全解決了問題。
第二種場景,相應的處理辦法具有一定的跨域數據交流功效,具有相當大的局限,並不適合在復雜業務流程中應用,實際上我也確實也沒看到過基於此的大規模應用。
第三種場景,相應的處理辦法比較巧妙,雖然redirect之後就不幹你什麼事了,但如果你是google一樣面向眾多域名的內容提供商,也是個不錯的解決思路。
第四種場景,相應的處理辦法非常強大,對比Ajax可以看到,跨域名沒問題,無刷新沒問題,本身又是非同步的,JSON比xml快的多,同時解決亂碼問題,只是請求都是Get方式的,不能做Post方式的請求。多一種武器自然可以從容選擇了
『拾』 前端解決跨域都有哪些方法
什麼是跨域?
瀏覽器發送的請求地址(URL)與所在頁面的地址 不同(埠/協議/域名 其一不同)。簡言之,瀏覽器發出的請求url,與其所在頁面的url不一樣。此時,同源策略會讓瀏覽器拒收 伺服器響應回來的數據,報錯信息如下:
最常用的四種跨域解決方案
1.cors
cors跨域資源共享允許是在服務端"Access-Control-Allow-Origin"欄位設置的,當將cors設置為允許某個地址訪問時,該地址就可以跨域訪問這個伺服器地址。當cors設置為"*"時即允許所有地址訪問時,則表示所有地址都可以跨域訪問這個伺服器地址的資源。
2、 通過jsonp跨域
Jsonp是Json的一種「使用模式」,他就可以解決瀏覽器遇到的跨域問題,我們可以動態創建script,再請求一個帶參網址實現跨域通信。用Jsonp請求得到的是JavaScript,相當於直接用JavaScript解析。
3、postMessage跨域
在h5中新增了postMessage方法,postMessage可以實現跨文檔消息傳輸,我們可以通過Windows的message事件來監聽發送跨文檔消息傳輸內容。
4、proxy(代理)
原理:因為同源策略只是針對瀏覽器的安全策略,但是服務端並不受同源策略的限制,也就不存在跨域的問題。