A. 前端解決跨域都有哪些方法
什麼是跨域?
瀏覽器發送的請求地址(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(代理)
原理:因為同源策略只是針對瀏覽器的安全策略,但是服務端並不受同源策略的限制,也就不存在跨域的問題。
B. 手機APP和web服務端 跨域問題
跨域問題來源於JavaScript的同源策略,即只有 協議+主機名+埠號 (如存在)相同,則允許相互訪問。也就是說JavaScript只能訪問和操作自己域下的資源,不能訪問和操作其他域下的資源。
在以前,前端和後端混雜在一起, 比如JavaScript直接調用同系統裡面的一個Httphandler,就不存在跨域的問題,但是隨著現代的這種多種客戶端的流行,比如一個應用通常會有Web端,App端,以及WebApp端,各種客戶端通常會使用同一套的後台處理邏輯,即API, 前後端分離的開發策略流行起來,前端只關注展現,通常使用JavaScript,後端處理邏輯和數據通常使用WebService來提供json數據。一般的前端頁面和後端的WebService API通常部署在不同的伺服器或者域名上。這樣,通過ajax請求WebService的時候,就會出現同源策略的問題。
需要說明的是,同源策略是JavaScript裡面的限制,其他的編程語言,比如在C#,Java或者iOS等其他語言中是可以調用外部的WebService,也就是說,如果開發Native應用,是不存在這個問題的,但是如果開發Web或者Html5如WebApp,通常使用JavaScript ajax對WebService發起請求然後解析返回的值,這樣就可能存在跨域的問題。
一般的,很容易想到,將外部的資源搬到同一個域上就能解決同源策略的限制的。即在Web網站上同時開發一個Http服務端頁面,所有JavaScript的請求都發到這個頁面上來,這個頁面在內部使用其他語言去調用外部的WebService。即添加一個代理層。這種方式可以解決問題,但是不夠直接和高效。
目前,比較常見的跨域解決方案包括JSONP (JSON with padding)和CORS (Cross-origin resource sharing )。一些解決方案需要客戶端和服務端配合如JSOP,一些則只需要服務端配合處理比如CORS。下面分別介紹這兩種跨域方案,以及服務端WebService如何支持這兩種跨域方案。
JSONP以及WebService的支持
同源策略下,某個伺服器是無法獲取到伺服器以外的數據,但是html裡面的img,iframe和script等標簽是個例外,這些標簽可以通過src屬性請求到其他伺服器上的數據。而JSONP就是通過script節點src調用跨域的請求。
當我們向伺服器提交一個JSONP的請求時,我們給服務傳了一個特殊的參數,告訴服務端要對結果特殊處理一下。這樣服務端返回的數據就會進行一點包裝,客戶端就可以處理。
舉個例子,服務端和客戶端約定要傳一個名為callback的參數來使用JSONP功能。比如請求的參數如下:
http://www.example.net/sample.aspx?callback=mycallback
如果沒有後面的callback參數,即不使用JSONP的模式,該服務的返回結果可能是一個單純的json字元串,比如:
{ foo : 'bar' }
如果和服務端約定jsonp格式,那麼服務端就會處理callback的參數,將返回結果進行一下處理,比如處理成:
mycallback({ foo : 'bar' })
可以看到,這其實是一個函數調用,比如可以實現在頁面定義一個名為mycallback的回調函數:
mycallback = function(data)
{
alert(data.foo);
};
現在,請求的返回值回去觸發回調函數,這樣就完了了跨域請求。
如果使用ServiceStack創建WebService的話,支持Jsonp方式的調用很簡單,只需要在AppHost的Configure函數裡面注冊一下對響應結果進行過濾處理即可。
/// <summary>
/// Application specific configuration
/// This method should initialize any IoC resources utilized by your web service classes.
/// </summary>
/// <param name="container"></param>
public override void Configure(Container container)
{
ResponseFilters.Add((req, res, dto) =>
{
var func = req.QueryString.Get("callback");
if (!func.isNullOrEmpty())
{
res.AddHeader("Content-Type", ContentType.Html);
res.Write("<script type='text/javascript'>{0}({1});</script>"
.FormatWith(func, dto.ToJson()));
res.Close();
}
});
}
JSONP跨域方式比較方便,也支持各種較老的瀏覽器,但是缺點很明顯,他只支持GET的方式提交,不支持其他Post的提交,Get方式對請求的參數長度有限制,在有些情況下可能不滿足要求。所以下面就介紹一下CORS的跨域解決方案。
CORS跨域及WebService的支持
先來看一個例子,我們新建一個基本的html頁面,在裡面編寫一個簡單的是否支持跨域的小腳本,如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>AJAX跨域請求測試</title>
</head>
<body>
<input type='button' value='開始測試' onclick='crossDomainRequest()' />
<div id="content"></div>
<script type="text/javascript">
//<![CDATA[
var xhr = new XMLHttpRequest();
var url = 'http://localhost:8078/json/ShopUserLogin';
function crossDomainRequest() {
document.getElementById("content").innerHTML = "開始……";
if (xhr) {
xhr.open('POST', url, true);
xhr.onreadystatechange = handler;
xhr.send();
} else {
document.getElementById("content").innerHTML = "不能創建 XMLHttpRequest";
}
}
function handler(evtXHR) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var response = xhr.responseText;
document.getElementById("content").innerHTML = "結果:" + response;
} else {
document.getElementById("content").innerHTML = "不允許跨域請求。";
}
}
else {
document.getElementById("content").innerHTML += "<br/>執行狀態 readyState:" + xhr.readyState;
}
}
//]]>
</script>
</body>
</html>
然後保存為本地html文件,可以看到,這個腳本中,對本地的服務http://localhost:1337/json/Hello 發起了一個請求, 如果使用chrome 直接打開,會看到輸出的結果,不允許跨域請求。 在javascript控制台程序中同樣可以看到錯誤提示:
那麼如果在返回響應頭header中注入Access-Control-Allow-Origin,這樣瀏覽器檢測到header中的Access-Control-Allow-Origin,則就可以跨域操作了。
同樣,如果使用ServcieStack,在很多地方可以支持CORS的跨域方式。最簡單的還是在AppHost的Configure函數裡面直接寫入:
/// <summary>
/// Application specific configuration
/// This method should initialize any IoC resources utilized by your web service classes.
/// </summary>
/// <param name="container"></param>
public override void Configure(Container container)
{
this.AddPlugin(new CorsFeature());
}
這樣就可以了,相當於使用默認的CORS配置:
CorsFeature(allowedOrigins:"*",
allowedMethods:"GET, POST, PUT, DELETE, OPTIONS",
allowedHeaders:"Content-Type",
allowCredentials:false);
如果僅僅允許GET和POST的請求支持CORS,則只需要改為:
Plugins.Add(new CorsFeature(allowedMethods: "GET, POST"));
當然也可以在AppHost的Config裡面設置全局的CORS,如下:
/// <summary>
/// Application specific configuration
/// This method should initialize any IoC resources utilized by your web service classes.
/// </summary>
/// <param name="container"></param>
public override void Configure(Container container)
{
base.SetConfig(new EndpointHostConfig
{
GlobalResponseHeaders = {
{ "Access-Control-Allow-Origin", "*" },
{ "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" },
{ "Access-Control-Allow-Headers", "Content-Type" },
},
});
}
現在運行WebService,使用postman或者Chrome調用這個請求,可以看到返回的值頭文件中,已經加上了響應頭,並且可以正常顯示返回結果了:
CORS使用起來簡單,不需要客戶端的額外處理,而且支持Post的方式提交請求,但是CORS的唯一一個缺點是對客戶端的瀏覽器版本有要求,支持CORS的瀏覽器機器版本如下:
總結
本文介紹了JavaScript中的跨域基本概念和產生的原因,以及如何解決跨域的兩種方法,一種是JSONP 一種是 CORS,在客戶端Javascript調用服務端介面的時候,如果需要支持跨域的話,需要服務端支持。JSONP的方式就是服務端對返回的值進行回調函數包裝,他的優點是支持眾多的瀏覽器, 缺點是僅支持Get的方式對服務端請求。另一種主流的跨域方案是CORS,他僅需要服務端在返回數據的時候在相應頭中加入標識信息。這種方式非常簡便。唯一的缺點是需要瀏覽器的支持,一些較老的瀏覽器可能不支持CORS特性。
跨域支持是創建WebService時應該考慮的一個功能點,希望本文對您在這邊面有所幫助,文中是使用ServiceStack來演示跨域支持的,如果您用的WCF的話,知道跨域原理的前提下,實現跨域應該不難。
參考資料:
https://github.com/ServiceStack/ServiceStack/wiki/Customize-HTTP-Responses
https://github.com/ServiceStack/ServiceStack/wiki/Request-and-response-filters
http://stackoverflow.com/questions/8211930/servicestack-rest-api-and-cors
http://stackoverflow.com/questions/15224038/rename-callback-parameter-for-jsonp
C. web前端跨域的一些解決方案
沒有歸納之前對跨域的一些說法是模糊的,什麼jsonp啊,跨域原理啊,心裡只有一個大概的說法,知道這個東西,然後用的時候直接網路Ctrl+C,後來閑下來決定整理一波這些知識點,需知其所以然。
那麼,其實這是瀏覽器對我們的一種保護機制,把壞人擋在門外。那麼,問題來了,我們怎麼確定門外的人到底是好人還是壞人呢?瀏覽器關上了壞人的一扇門,留給了我們好人一扇窗。
JSONP跟JSON沒有關系..就好像JavaScript和Java一樣
瀏覽器對script、img(這些標簽的請求方式都是 GET ,所以jsonp不支持 POST )這種標簽沒有限制,我們就可以這樣干
因此,實現CORS通信的關鍵是伺服器。只要伺服器實現了CORS介面,就可以跨源通信。
伺服器端對於CORS的支持,主要就是通過設置 Access-Control-Allow-Origin 來進行的。如果瀏覽器檢測到相應的設置,就可以允許Ajax進行跨域的訪問。 更多有關跨域資源共享 CORS 的知識
瀏覽器中可以查看對應的響應頭,舉個例子,如下
服務端允許CORS,服務端需要針對介面設置的一系列響應頭 (Response Headers)
1.簡單請求
目前大多數情況都採用這種方式。簡單請求只需要設置 Access-Control-Allow-Origin 即可。滿足以下兩個條件,就屬於簡單請求。
2.非簡單請求
非簡單請求會發出一次預檢測請求,返回碼是204,預檢測通過才會真正發出請求,這才返回200。來看栗子:
非簡單請求需要根據不同情況配置不同的響應頭,一系列響應頭配置項見上方
這個說法相信不陌生,我們依然使用前端域名請求,然後有一個 中介商---代理 把這個請求轉發到真正的後端域名上,那也就不存在跨域問題了。
比較普遍的Nginx,簡單的配置一下就可以了。了解更多的配置信息: nginx詳解
然後前端這邊的請求地址是 http://localhost:9099/api/xxx ,然後Nginx監聽到地址是 localhost:9099/api 的請求,就幫我們轉發到真正的服務端地址 http://.com
CORS與JSONP的使用目的相同,但是比JSONP更強大。JSONP只支持GET請求,CORS支持所有類型的HTTP請求。JSONP的優勢在於支持老式瀏覽器,以及在服務端同意jsonp方式時,可以向不支持CORS的網站請求數據。Nginx可以說是最方便的,不過需要部署Nginx才行,需要對伺服器有一定的理解,不太適合剛入門的同學,當然也可以請後台同學幫忙部署。
window.postMessage(data,origin) 是 HTML5 的一個介面,專注實現不同窗口不同頁面的跨域通訊。
現在是這么一個情況,由於同源策略的限制下, a.html 不能操作iframe( b.html )裡面的dom,那麼使用postMessage就可以解決這一情況
然後 b.html 頁面通過message事件監聽並接受消息:
這種方式只適合主域名相同,但子域名不同的iframe跨域。
比如主域名是 http://.com/:8888 ,子域名是 http://child..com/:8888 ,這種情況下給兩個頁面設置相同的document.domain即document.domain = .com 就可以訪問各自的window對象了。
前端跨域整理
不要再問我跨域的問題了
D. 跨域問題解決方法
跨域?他是瀏覽器的 同源策略 造成的,是瀏覽器對javascript施加的安全限制。所謂同源是指:域名、協議、埠均相同。
解決
原理:利用標簽具有可跨域的特性,可實現跨域訪問介面,需要後端的支持。
伺服器在收到請求後,解析參數,計算返還數據,輸出messagetow(data)字元串。
缺點:只能發送get請求,無法訪問伺服器的響應文本(單向請求),即只能獲取數據不能改數據。
通過ajax請求不同域的實現,底層不是靠XmlHttpRequest而是script,所以不要被這個方法給迷惑了。
在ajax請求中類型如果是type是get post,其實內部都只會用get,因為其跨域的原理就是用的動態載入script的src,所以我們只能把參數通過url的方式傳遞
其實jquery內部會轉化成
http://192.168.31.137/train/test/jsonpthree?callback=messagetow
然後動態載入http://192.168.1.114/yii/demos/test.php?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron">
http://192.168.1.114/yii/demos/test.php?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron"><script type="text/javascript" src=" http://192.168.31.137/train/test/jsonpthree?callback=messagetow "></script>
http://192.168.1.114/yii/demos/test.php?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron">
http://192.168.1.114/yii/demos/test.php?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron">
Cross-Origin Resource Sharing(CORS)跨域資源共享是一份瀏覽器技術的規范,提供了 Web 服務從不同域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,確保安全的跨域數據傳輸。現代瀏覽器使用CORS在API容器如XMLHttpRequest來減少HTTP請求的風險來源。與 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。伺服器一般需要增加如下響應頭的一種或幾種:
跨域請求默認不會攜帶Cookie信息,如果需要攜帶,請配置下述參數:
window.name通過在iframe(一般動態創建i)中載入跨域HTML文件來起作用。然後,HTML文件將傳遞給請求者的字元串內容賦值給window.name。然後,請求者可以檢索window.name值作為響應。
iframe標簽的跨域能力;
window.name屬性值在文檔刷新後依舊存在的能力(且最大允許2M左右)。
每個iframe都有包裹它的window,而這個window是top window的子窗口。 contentWindow 屬性返回<iframe>元素的Window對象。你可以使用這個Window對象來訪問iframe的文檔及其內部DOM。
HTML5新特性,可以用來向其他所有的 window 對象發送消息。需要注意的是我們必須要保證所有的腳本執行完才發送 MessageEvent,如果在函數執行的過程中調用了它,就會讓後面的函數超時無法執行。
前提條件:這兩個域名必須屬於同一個基礎域名!而且所用的協議,埠都要一致,否則無法利用document.domain進行跨域,所以只能跨子域
在 根域 范圍內,允許把domain屬性的值設置為它的上一級域。例如,在」aaa.xxx.com」域內,可以把domain設置為 「xxx.com」 但不能設置為 「xxx.org」 或者」com」。
現在存在兩個域名aaa.xxx.com和bbb.xxx.com。在aaa下嵌入bbb的頁面,由於其document.name不一致,無法在aaa下操作bbb的js。可以在aaa和bbb下通過js將document.name = 'xxx.com';設置一致,來達到互相訪問的作用。
WebSocket protocol 是HTML5一種新的協議。它實現了瀏覽器與伺服器全雙工通信,同時允許跨域通訊,是server push技術的一種很棒的實現。相關文章,請查看: WebSocket 、 WebSocket-SockJS
**需要注意:**WebSocket對象不支持DOM 2級事件偵聽器,必須使用DOM 0級語法分別定義各個事件。
同源策略是針對瀏覽器端進行的限制,可以通過伺服器端來解決該問題,例如nginx
DomainA客戶端(瀏覽器) ==> DomainA伺服器 ==> DomainB伺服器 ==> DomainA客戶端(瀏覽器)
E. 跨域是指什麼,因為什麼引起的有哪些解決方案web前端知識
廣義跨域就是指跨域訪問,簡單來說就是 A 網站的 javascript 代碼試圖訪問 B 網站,包括提交內容和獲取內容。由於安全原因,跨域訪問是被各大瀏覽器所默認禁止的。
當一個域與其他域建立了信任關系後,2個域之間不但可以按需要相互進行管理,還可以跨網分配文件和列印機等設備資源,使不同的域之間實現網路資源的共享與管理。這就形成了「跨域」。
F. rust actix_web解決跨域問題
在做Web服務時使用的是與主站 配置的是fb.net , 另外個成員列表服務是 m1.fb.net ,這會造成一個跨域問題。在瀏覽器下使用 XML Http Request 或者 fetch 發出一個HTTP請求,假如這個HTTP的協議、主機名或者埠任意一個與當前網頁地址有不一致時,為了安全瀏覽器會限制響應結果,通常這類問題就是所謂的跨域問題。
可以參考: https://segmentfault.com/a/1190000012550346
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
解決跨域問題的方式有很多,比如 jsonp , iframe 等等。但在這里,我使用HTTP協議里約定的欄位來解決這個問題,這也是最干凈完美的解決方案。為了處理有跨域請求的特殊場景,HTTP協議里有一個特殊的響應頭欄位 Access-Control-Allow-Origin ,意思允許訪問的 Origin ,值可以是通配符 * ,允許所有,或者寫上一個具體的 Origin 值。
在 actix-web 里, 我們需要配合 actix_cors 來處理關於跨域請求的配置,以下是一個例子
Cargo.toml
main.rs
測試一下
如果我們把Origin換成另一個域名,則會報錯
400出錯了,提示
不允許的Origin請求,另外http和https視為不同的origin,都需要添加支持。
如果你需要允許所有的 Origin ,也就是不做限制的話,那麼使用 * 號做通配符
通常來說不建議這么干,
當然如果有nginx做負載的話,也可以在nginx上部署,此時後端服務可以不用如此實現了,否則可能會出現:
G. http網頁建立websocket跨域問題,怎麼解決
websocket是htm5提供的一種全雙工通訊的協議。
websocket不存在跨域問題,html網頁通過new Websocket(url,[protocol]);創建對象。
看你的提示應該是使用了ajax請求。
H. 怎麼解決伺服器間的跨域問題
跨域指的是瀏覽器的一種安全機制,伺服器之間不存在跨域問題
如果兩台伺服器之間無法訪問,請檢查伺服器的防火牆配置是否阻止了二者之間的通信
望採納