常見跨域解決方案

跨域

JSONP

使用<script>標(biāo)簽不受同源策略影響的特性,作為Ajax傳輸技術(shù)稱為JSONP。

使用JSONP時(shí)贯莺,需要服務(wù)器返回一個(gè)實(shí)際內(nèi)容作為一個(gè)函數(shù)參數(shù)的函數(shù)執(zhí)行語句风喇。

//整個(gè)函數(shù)作為返回主體,實(shí)際的響應(yīng)主體
handleResponse(
//目標(biāo)需要的響應(yīng)主體
[1,2,{"buckle":"my shoe"}]
)

handleResponse()的表達(dá)式在客戶端完成,通過<script>標(biāo)簽使用JSONP后,在客戶端上會執(zhí)行handleResponse(data)函數(shù)達(dá)到獲取數(shù)據(jù)的目的乖篷。

通常情況為了使用方便响驴,在URL中添加一個(gè)查詢參數(shù)來表示返回的執(zhí)行函數(shù)的函數(shù)名透且。

示例

//一個(gè)響應(yīng)處理函數(shù)
function handleResponse(response){
  alert("You're at IP address " + response.id + ".");
}
var script = document.creatElement("script");
//在url中添加一個(gè)查詢參數(shù)指明響應(yīng)處理函數(shù)名稱
script.src = "http://XXX.XXX/XX?callback=handleResponse";
document.body.insertBefore(script,document.body.firstChild);

CORS跨域資源共享

CORS(Cross-Origin Resource Sharing)是一種跨域獲取資源的解決方案撕蔼。思想是使用自定義的http頭讓瀏覽器與服務(wù)器溝通,從而決定請求或響應(yīng)是否成功秽誊。(ie10以下不支持)

客戶端在發(fā)送請求的時(shí)候添加一個(gè)額外的頭部信息Origin頭部鲸沮,內(nèi)容包含請求頁面的源信息(協(xié)議、域名和端口)锅论,服務(wù)器根據(jù)這個(gè)頭部信息來決定是否給予響應(yīng)讼溺。如果服務(wù)器認(rèn)為這個(gè)請求可以接受,就在Access-Control-Allow-Origin頭部中發(fā)回相同的源信息最易。如果服務(wù)器返回的響應(yīng)沒有這個(gè)頭部或者頭部的源信息不匹配怒坯,瀏覽器就會駁回。

客戶端對于請求分為兩類藻懒,簡單請求和非簡單請求剔猿。

簡單請求

CORS對于簡單請求只是在頭信息中添加Origin字段,這個(gè)字段說明本次請求來自哪個(gè)源嬉荆,即發(fā)送請求的頁面地址归敬。發(fā)送請求以后,瀏覽器會接收服務(wù)器的響應(yīng)鄙早,當(dāng)響應(yīng)成功時(shí)http碼200汪茧,在響應(yīng)頭中Access-Control-Allow-Origin 字段中出現(xiàn)請求頁面的地址,則請求頁面可以接收到來自服務(wù)器的信息,否則頁面不能獲取響應(yīng)的信息限番,但是實(shí)際信息已經(jīng)發(fā)送到瀏覽器舱污,由于同源策略的原因不可訪問。

Access-Control-Allow-Origin 該字段是必須的弥虐。它的值要么是請求時(shí)Origin字段的值扩灯,要么是一個(gè)*,表示接受任意域名的請求躯舔。

Access-Control-Allow-Credentials 字段表示是否允許發(fā)送Cookie驴剔。如果這個(gè)字段為true,表明可以接收cookie粥庄。xhr.withCredentials = true; 在瀏覽器上設(shè)置發(fā)送cookie;

Access-Control-Expose-Headers 字段表示獲取的響應(yīng)頭的其他字段丧失。

非簡單請求

非簡單請求是指請求方法為PUTDELETE,或者Content-Typeapplication/json惜互。對于這樣的請求CORS會在正式請求之前發(fā)送一次預(yù)請求布讹。

預(yù)請求的方法是OPTIONS 琳拭,預(yù)請求的頭信息里包括Origin Methods Headers三個(gè)字段。

? Access-Control-Allow-Origin同簡單請求

? Access-Control-Allow-Methods該字段必需描验,它的值是逗號分隔的一個(gè)字符串白嘁,表明服務(wù)器支持的所有跨域請求的方法。注意膘流,返回的是所有支持的方法絮缅,而不單是瀏覽器請求的那個(gè)方法。這是為了避免多次"預(yù)檢"請求呼股。

? Access-Control-Allow-Headers該字段是一個(gè)逗號分隔的字符串耕魄,指定瀏覽器CORS請求會額外發(fā)送的頭信息字段。

如果瀏覽器否定了預(yù)請求彭谁,會返回一個(gè)正常的HTTP響應(yīng)吸奴,但是響應(yīng)頭中沒有任何CORS的信息。這時(shí)會觸發(fā)XMLHttpRequest對象的onerror方法缠局。

<script>
    document.cookie = "This is Cookie";
    var xhr = new XMLHttpRequest();
    var url = 'http://localhost:8081/';
    xhr.open('GET',url);
    xhr.setRequestHeader('X-Custom-Header', 'value');
    xhr.onreadystatechange = function (){
        if(xhr.readyState ===4){
            if(xhr.status === 200){
                var span = document.getElementById("span");
                span.innerHTML = xhr.responseText;
                alert(xhr.responseText);
            }
        }
    };
  //發(fā)送cookie
    xhr.withCredentials = true;
    xhr.send(null);
    console.log(document.cookie);
</script>
var http = require('http');
var message = "This is massage";
http.createServer(function(req,res){
    res.setHeader("Content-type","text/text");
    res.setHeader("Access-Control-Allow-Origin","http://localhost:63342");
    res.setHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE");
    res.setHeader("Access-Control-Allow-Credentials",true);
  //設(shè)置允許的請求頭中出現(xiàn)的字段
    res.setHeader("Access-Control-Allow-Headers","X-Custom-Header");
    res.writeHead(200);
    res.write(message);
    res.end(" end");
}).listen(8081);

WebSocket

WebSocket是一種通信協(xié)議则奥,使用ws://wss://作為協(xié)議前綴,該協(xié)議是一種全雙工的協(xié)議狭园,http是一種半雙工協(xié)議读处。利用該協(xié)議不受同源策略限制的情況,可以使用該協(xié)議作為跨域通信的方式妙啃。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末档泽,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子揖赴,更是在濱河造成了極大的恐慌馆匿,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件燥滑,死亡現(xiàn)場離奇詭異渐北,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)铭拧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門赃蛛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人搀菩,你說我怎么就攤上這事呕臂。” “怎么了肪跋?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵歧蒋,是天一觀的道長。 經(jīng)常有香客問我,道長谜洽,這世上最難降的妖魔是什么萝映? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮阐虚,結(jié)果婚禮上序臂,老公的妹妹穿的比我還像新娘。我一直安慰自己实束,他們只是感情好奥秆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著磕洪,像睡著了一般吭练。 火紅的嫁衣襯著肌膚如雪诫龙。 梳的紋絲不亂的頭發(fā)上析显,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天叭爱,我揣著相機(jī)與錄音缴渊,去河邊找鬼周偎。 笑死崖媚,一個(gè)胖子當(dāng)著我的面吹牛计呈,可吹牛的內(nèi)容都是我干的业踢。 我是一名探鬼主播届慈,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼截碴,長吁一口氣:“原來是場噩夢啊……” “哼孔庭!你這毒婦竟也來了尺上?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤圆到,失蹤者是張志新(化名)和其女友劉穎怎抛,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芽淡,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡马绝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挣菲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片富稻。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖白胀,靈堂內(nèi)的尸體忽然破棺而出椭赋,到底是詐尸還是另有隱情,我是刑警寧澤或杠,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布哪怔,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏蔓涧。R本人自食惡果不足惜件已,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望元暴。 院中可真熱鬧篷扩,春花似錦、人聲如沸茉盏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸠姨。三九已至铜秆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間讶迁,已是汗流浹背连茧。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留巍糯,地道東北人啸驯。 一個(gè)月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像祟峦,于是被迫代替她去往敵國和親罚斗。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容