AJAX跨域問(wèn)題講解

為什么會(huì)發(fā)生產(chǎn)生跨域問(wèn)題空入?

[ 產(chǎn)生跨域的原因 ]

1.瀏覽器限制
2.跨域(協(xié)議,域名咖城,端口任何一個(gè)不同)
3.XHR(XMLHttpRequest)請(qǐng)求

也就是說(shuō)當(dāng)我們發(fā)送的是XMLHttpRequest請(qǐng)求不同的域名茬腿,瀏覽器就會(huì)限制訪問(wèn),那么就會(huì)產(chǎn)生跨域問(wèn)題宜雀。

[ 解決跨域問(wèn)題的思路 ]

1.改動(dòng)客戶端瀏覽器參數(shù)來(lái)解除限制 瀏覽器啟動(dòng)加入 --disable-web-security
2.Jsonp解決是XHR請(qǐng)求的問(wèn)題.
3.跨域: 被調(diào)用方支持跨域切平,調(diào)用方的隱藏請(qǐng)求

跨域問(wèn)題解決辦法

1. JSONP解決跨域

[原理]:<script>請(qǐng)求不受同源政策限制 :JSONP動(dòng)態(tài)創(chuàng)建<script>標(biāo)簽,通過(guò)<script>函數(shù)調(diào)用發(fā)出請(qǐng)求辐董,返回值是也是js悴品,函數(shù)名callback參數(shù)的值,函數(shù)參數(shù)是返回的json對(duì)象()
[弊端]:1.只支持Get請(qǐng)求2.發(fā)送到不是XHR請(qǐng)求

[jsonp請(qǐng)求實(shí)現(xiàn)]
$.ajax({
    url: 'url",
    dataType: "jsonp",
    jsonp: "callback",
    cache: true,
    success: function(json) {
        result = json;
    }
});
[jsonp請(qǐng)求實(shí)現(xiàn)原理]
//動(dòng)態(tài)創(chuàng)建script標(biāo)簽
function addScriptTag(src) {
  var script = document.createElement('script');
  script.setAttribute("type","text/javascript");
  script.src = src;
  document.body.appendChild(script);
}

window.onload = function () {
  addScriptTag('http://example.com/ip?callback=foo');
}
// 回調(diào)函數(shù)-獲取數(shù)據(jù)
function foo(data) {
  console.log('Your public IP address is: ' + data.ip);
};

2. 跨域解決方案CORS

CORS是一個(gè)W3C標(biāo)準(zhǔn)简烘,全稱是”跨域資源共享”(Cross-origin resource sharing)苔严。CORS需要瀏覽器和服務(wù)器同時(shí)支持。目前孤澎,所有瀏覽器都支持該功能届氢,IE瀏覽器不能低于IE10。

它允許瀏覽器向跨源服務(wù)器覆旭,發(fā)出XMLHttpRequest請(qǐng)求退子,從而克服了AJAX只能同源使用的限制岖妄。整個(gè)CORS通信過(guò)程,都是瀏覽器自動(dòng)完成寂祥,不需要用戶參與衣吠。對(duì)于開發(fā)者來(lái)說(shuō),CORS通信與同源的AJAX通信沒(méi)有差別壤靶,代碼完全一樣。瀏覽器一旦發(fā)現(xiàn)AJAX請(qǐng)求跨源惊搏,就會(huì)自動(dòng)添加一些附加的頭信息贮乳,有時(shí)還會(huì)多出一次附加的請(qǐng)求,但用戶不會(huì)有感覺(jué)恬惯。因此向拆,實(shí)現(xiàn)CORS通信的關(guān)鍵是服務(wù)器。只要服務(wù)器實(shí)現(xiàn)了CORS接口酪耳,就可以跨源通信浓恳。

[簡(jiǎn)單請(qǐng)求-post請(qǐng)求]

解決:被調(diào)用放服務(wù)端設(shè)置Access-Control-Allow-Origin

被調(diào)用放服務(wù)端設(shè)置Access-Control-Allow-Methods

res.addHeader("Access-Control-Allow-Origin", "*") //允許所有域名可以跨域調(diào)用
res.addHeader("Access-Control-Allow-Methods", "*") //允許所有請(qǐng)求方式跨域調(diào)用

[非簡(jiǎn)單請(qǐng)求-帶cookie的請(qǐng)求]
$.ajax({
    type: "get",
    url: "url",
    xhrFields: {
        withCredentials: true
    },
    success: function(json) {
        result = json;
    }
});

解決:帶cookie時(shí)origin必須全匹配, 不能使用 *

被調(diào)用放服務(wù)端增加設(shè)置Access-Control-Allow-Credentials

res.addHeader("Access-Control-Allow-Origin", "localhost:8081")
res.addHeader("Access-Control-Allow-Methods", "*")
res.addHeader("Access-Control-Allow-Credentials", "true") //enable cookie
[非簡(jiǎn)單請(qǐng)求-帶header的請(qǐng)求]
$.ajax({
    type: "get",
    url: 'url",
    headers: {
        "x-header1": "AAA"
    },
    beforeSend: function(xhr) {
        xhr.setRequestHeader("x-header2", "BBB")
    },
    success: function(json) {
        result = json;
    }
});

解決:帶cookie時(shí)origin必須全匹配碗暗, 不能使用 *

被調(diào)用放服務(wù)端增加設(shè)置Access-Control-Allow-Header

res.addHeader("Access-Control-Allow-Origin", "*")
res.addHeader("Access-Control-Allow-Methods", "*")
res.addHeader("Access-Control-Allow-Header", "content-Type,x-header1,x-header2")

綜上所述:

//帶cookie的時(shí)候颈将,origin必須是全匹配,不能使用*
String origin = req.getHeader("Origin");
if (!org.springframework.util.StringUtils.isEmpty(origin)) {
    res.addHeader("Access-Control-Allow-Origin", origin);
}
res.addHeader("Access-Control-Allow-Methods", "*");

// 支持所有自定義頭和預(yù)檢命令(非簡(jiǎn)單請(qǐng)求會(huì)有預(yù)檢命令)
String headers = req.getHeader("Access-Control-Request-Headers");
if (!org.springframework.util.StringUtils.isEmpty(headers)) {
    res.addHeader("Access-Control-Allow-Headers", headers);         
}

res.addHeader("Access-Control-Max-Age", "3600");
// enable cookie
res.addHeader("Access-Control-Allow-Credentials", "true");

3. Nginx代理

如果我們請(qǐng)求的時(shí)候還是用前端的域名言疗,Nginx幫我們把這個(gè)請(qǐng)求轉(zhuǎn)發(fā)到真正的后端域名上

[Nginx配置]
server{
    # 監(jiān)聽9000端口
    listen 9000;
    # 域名是localhost
    server_name localhost;
    #凡是localhost:9000/api這個(gè)樣子的晴圾,都轉(zhuǎn)發(fā)到真正的服務(wù)端地址http://localhost:9001
    location ^~ /api {
        proxy_pass http://localhost:9001;
    }    
}

簡(jiǎn)單請(qǐng)求&非簡(jiǎn)單請(qǐng)求

只要同時(shí)滿足以下兩大條件,就屬于簡(jiǎn)單請(qǐng)求,其余屬于非簡(jiǎn)單請(qǐng)求

(1) 請(qǐng)求方法是以下三種方法之一:HEAD噪奄、GET死姚、POST

(2)HTTP的頭信息不超出以下幾種字段(無(wú)自定義頭):

  Accept
  Accept-Language
  Content-Language
  Last-Event-ID

(3)Content-Type:只限于三個(gè)值

  application/x-www-form-urlencoded
  multipart/form-data
  text/plain

碼字不易,如果覺(jué)得對(duì)您有幫助勤篮,給個(gè)贊給一個(gè)小小的鼓勵(lì)吧 (.)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末都毒,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子碰缔,更是在濱河造成了極大的恐慌账劲,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件手负,死亡現(xiàn)場(chǎng)離奇詭異涤垫,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)竟终,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門蝠猬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人统捶,你說(shuō)我怎么就攤上這事榆芦”猓” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵匆绣,是天一觀的道長(zhǎng)驻右。 經(jīng)常有香客問(wèn)我,道長(zhǎng)崎淳,這世上最難降的妖魔是什么堪夭? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮拣凹,結(jié)果婚禮上森爽,老公的妹妹穿的比我還像新娘。我一直安慰自己嚣镜,他們只是感情好爬迟,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著菊匿,像睡著了一般付呕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上跌捆,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天徽职,我揣著相機(jī)與錄音,去河邊找鬼疹蛉。 笑死活箕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的可款。 我是一名探鬼主播育韩,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼闺鲸!你這毒婦竟也來(lái)了筋讨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤摸恍,失蹤者是張志新(化名)和其女友劉穎悉罕,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體立镶,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壁袄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了媚媒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗜逻。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖缭召,靈堂內(nèi)的尸體忽然破棺而出栈顷,到底是詐尸還是另有隱情逆日,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布萄凤,位于F島的核電站室抽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏靡努。R本人自食惡果不足惜坪圾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望惑朦。 院中可真熱鬧神年,春花似錦、人聲如沸行嗤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)栅屏。三九已至,卻和暖如春堂鲜,著一層夾襖步出監(jiān)牢的瞬間栈雳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工缔莲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哥纫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓痴奏,卻偏偏與公主長(zhǎng)得像蛀骇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子读拆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355