AJAX-跨域請(qǐng)求

1窗看、什么是跨域請(qǐng)求

瀏覽器均默認(rèn)開啟了同源策略茸歧,它指Ajax請(qǐng)求所在的頁面和被請(qǐng)求的頁面在域名、端口均相同才能被訪問显沈,否則會(huì)提示如下錯(cuò)誤:

XMLHttpRequest cannot load xxxxxxx is not allowed by 
Access-Control-Allow-Origin.

2举娩、JSONP解決方案

2.1 JSONP原理

JSONP 不是真正的AJAX請(qǐng)求,是利用script的src可可以跨域的特性构罗,動(dòng)態(tài)加載一段script腳本,腳本中包含需要的信息智玻。

2.2 基礎(chǔ)代碼實(shí)現(xiàn)

html源代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonp跨域</title>
    <script type="text/javascript">
        function callbak(rs){
            alert(rs.data);
        }
    </script>
    <script src="http://127.0.0.1:8080"></script>
</head>
<body>
</body>
</html>

node js 服務(wù)器代碼:

//調(diào)用http模塊
var http = require('http'); 
var server = http.createServer(function (request, response) {
     response.writeHead(200, {
        'Content-Type': 'application/javascript'
    });
    response.write("callbak({'data':'jsonp'});");
    response.end();
   
});
server.listen(8080);
//打印日志
console.log('Http server is started. http://127.0.0.1:8080');

注意:
(1)函數(shù)名callbak 前端與后端需要一致
(2)服務(wù)器反饋的數(shù)據(jù)類型application/javascript 類型

2.3 JSONP 公用函數(shù)封裝遂唧。

前端代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jsonp跨域</title>
</head>
<body id="body">
</body>
<!-- 主要要在body之后,否則document.body為null-->
<script type="text/javascript">
        function jsonp(url,callback){
            //動(dòng)態(tài)生成函數(shù)名稱
            var funcName= "callback"+new Date().getTime();
            //添加callback參數(shù)到url中(假設(shè)url中沒有其他參數(shù))
            url = url + "?callback="+funcName;
            //設(shè)置全局函數(shù)是傳人行數(shù)
            window[funcName] = callback;
            //創(chuàng)建Script標(biāo)簽
            var script = document.createElement("script");
            script.src = url;
            //添加到body中
            var body = document.body;
            body.appendChild(script);
            //動(dòng)態(tài)標(biāo)簽加載完成
            script.onload = function(){
                //刪除script標(biāo)簽
                body.removeChild(script);
                //刪除全局函數(shù)
                window[funcName] = null;
            }
        }
        var url = "http://127.0.0.1:8080";
        jsonp(url,function(rs){
            alert(rs.data);
        });
    </script>
</html>

node js 后端代碼:

//調(diào)用http模塊
var http = require('http'); 
var url = require('url');
var server = http.createServer(function (request, response) {
     response.writeHead(200, {
        'Content-Type': 'application/javascript'
    });
    //請(qǐng)求參數(shù)轉(zhuǎn)換為json格式
    var arg = url.parse(request.url, true).query;
    //獲取回調(diào)方法名稱
    var funcName = arg.callback;
    response.write(funcName + "({'data':'jsonp'});");
    response.end();
   
});
server.listen(8080);
//打印日志
console.log('Http server is started. http://127.0.0.1:8080');

3吊奢、CROS解決方案

3.1 CROS簡(jiǎn)單

CORS需要瀏覽器和服務(wù)器同時(shí)支持盖彭。只有支持XmlHttpRequest Level2的瀏覽器才支持纹烹。
??整個(gè)CORS通信過程,都是瀏覽器自動(dòng)完成召边,不需要用戶參與铺呵。對(duì)于開發(fā)者來說,CORS通信與同源的AJAX通信沒有差別隧熙,代碼完全一樣片挂。瀏覽器一旦發(fā)現(xiàn)AJAX請(qǐng)求跨源,就會(huì)自動(dòng)添加一些附加的頭信息贞盯,有時(shí)還會(huì)多出一次附加的請(qǐng)求音念,但用戶不會(huì)有感覺。
??因此躏敢,實(shí)現(xiàn)CORS通信的關(guān)鍵是服務(wù)器闷愤。只要服務(wù)器實(shí)現(xiàn)了CORS接口,就可以跨源通信件余。

3.2 CROS服務(wù)器端設(shè)置

(1)Access-Control-Allow-Origin
??該字段是必須的讥脐。它的值要么是請(qǐng)求時(shí)Origin字段的值,要么是一個(gè)*啼器,表示接受任意域名的請(qǐng)求旬渠。

(2)Access-Control-Request-Method
??該字段是必須的,列出瀏覽器的CORS請(qǐng)求會(huì)用到哪些HTTP方法镀首。

**(3)Access-Control-Expose-Headers **
??該字段可選坟漱。CORS請(qǐng)求時(shí),XMLHttpRequest對(duì)象的getResponseHeader()方法只能拿到6個(gè)基本字段:Cache-Control更哄、Content-Language芋齿、Content-Type、Expires成翩、Last-Modified觅捆、Pragma。如果想拿到其他字段麻敌,就必須在Access-Control-Expose-Headers里面指定栅炒。
**(4)Access-Control-Allow-Credentials **
??該字段可選。它的值是一個(gè)布爾值术羔,表示是否允許發(fā)送Cookie赢赊。默認(rèn)情況下,Cookie不包括在CORS請(qǐng)求之中级历。設(shè)為true释移,即表示服務(wù)器明確許可,Cookie可以包含在請(qǐng)求中寥殖,一起發(fā)給服務(wù)器玩讳。這個(gè)值也只能設(shè)為true涩蜘,如果服務(wù)器不要瀏覽器發(fā)送Cookie,刪除該字段即可熏纯。
(5)Access-Control-Max-Age
??該字段可選同诫,用來指定本次預(yù)檢請(qǐng)求的有效期,單位為秒樟澜,在此期間误窖,不用發(fā)出另一條預(yù)檢請(qǐng)求。

3.3 CROS跨域Cookie

CORS請(qǐng)求默認(rèn)不發(fā)送Cookie和HTTP認(rèn)證信息往扔。如果要把Cookie發(fā)到服務(wù)器贩猎,一方面要服務(wù)器同意,指定Access-Control-Allow-Credentials字段,設(shè)置** Access-Control-Allow-Credentials: true**萍膛。

Access-Control-Allow-Credentials: true

另一方面吭服,開發(fā)者必須在AJAX請(qǐng)求中打開withCredentials屬性。

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

否則蝗罗,即使服務(wù)器同意發(fā)送Cookie艇棕,瀏覽器也不會(huì)發(fā)送〈埽或者沼琉,服務(wù)器要求設(shè)置Cookie,瀏覽器也不會(huì)處理桩匪。但是打瘪,如果省略withCredentials設(shè)置,有的瀏覽器還是會(huì)一起發(fā)送Cookie傻昙。這時(shí)闺骚,可以顯式關(guān)閉withCredentials,設(shè)置withCredentials=false;
特別注意
需要注意的是,如果要發(fā)送Cookie妆档,Access-Control-Allow-Origin就不能設(shè)為星號(hào)僻爽,必須指定明確的、與請(qǐng)求網(wǎng)頁一致的域名贾惦。同時(shí)胸梆,Cookie依然遵循同源政策,只有用服務(wù)器域名設(shè)置的Cookie才會(huì)上傳须板,其他域名的Cookie并不會(huì)上傳碰镜,且(跨源)原網(wǎng)頁代碼中的document.cookie也無法讀取服務(wù)器域名下的Cookie烙博。

3.4 CROS預(yù)檢

(1)預(yù)檢查概述
??非簡(jiǎn)單請(qǐng)求的CORS請(qǐng)求鞍泉,會(huì)在正式通信之前,增加一次HTTP查詢請(qǐng)求淌铐,稱為"預(yù)檢"請(qǐng)求(preflight)杰刽。瀏覽器先詢問服務(wù)器菠发,當(dāng)前網(wǎng)頁所在的域名是否在服務(wù)器的許可名單之中,以及可以使用哪些HTTP動(dòng)詞和頭信息字段贺嫂。只有得到肯定答復(fù)滓鸠,瀏覽器才會(huì)發(fā)出正式的XMLHttpRequest請(qǐng)求,否則就報(bào)錯(cuò)第喳。
(2)預(yù)檢查請(qǐng)求
??"預(yù)檢"請(qǐng)求用的請(qǐng)求方法是OPTIONS糜俗,表示這個(gè)請(qǐng)求是用來詢問的。頭信息里面曲饱,關(guān)鍵字段是Origin悠抹,表示請(qǐng)求來自哪個(gè)源。除了Origin字段扩淀,"預(yù)檢"請(qǐng)求的頭信息包括兩個(gè)特殊字段楔敌。Access-Control-Request-MethodAccess-Control-Request-Headers
(3)預(yù)檢查響應(yīng)
??服務(wù)器收到"預(yù)檢"請(qǐng)求以后,檢查了Origin驻谆、Access-Control-Request-Method和Access-Control-Request-Headers字段以后卵凑,確認(rèn)允許跨源請(qǐng)求,就可以做出回應(yīng)胜臊∩茁回應(yīng)的內(nèi)容參考服務(wù)端配置。

3.5 CROS 正常請(qǐng)求與回應(yīng)

一旦服務(wù)器通過了"預(yù)檢"請(qǐng)求象对,以后每次瀏覽器正常的CORS請(qǐng)求黑忱,就都跟簡(jiǎn)單請(qǐng)求一樣,會(huì)有一個(gè)Origin頭信息字段勒魔。服務(wù)器的回應(yīng)甫煞,也都會(huì)有一個(gè)Access-Control-Allow-Origin頭信息字段。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末沥邻,一起剝皮案震驚了整個(gè)濱河市危虱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌唐全,老刑警劉巖埃跷,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異邮利,居然都是意外死亡弥雹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門延届,熙熙樓的掌柜王于貴愁眉苦臉地迎上來剪勿,“玉大人,你說我怎么就攤上這事方庭〔藜” “怎么了酱固?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)头朱。 經(jīng)常有香客問我运悲,道長(zhǎng),這世上最難降的妖魔是什么项钮? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任班眯,我火速辦了婚禮,結(jié)果婚禮上烁巫,老公的妹妹穿的比我還像新娘署隘。我一直安慰自己,他們只是感情好亚隙,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布磁餐。 她就那樣靜靜地躺著,像睡著了一般恃鞋。 火紅的嫁衣襯著肌膚如雪崖媚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天恤浪,我揣著相機(jī)與錄音畅哑,去河邊找鬼。 笑死水由,一個(gè)胖子當(dāng)著我的面吹牛荠呐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播砂客,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼泥张,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了鞠值?” 一聲冷哼從身側(cè)響起媚创,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎彤恶,沒想到半個(gè)月后钞钙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡声离,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年芒炼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片术徊。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡本刽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情子寓,我是刑警寧澤暗挑,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站斜友,受9級(jí)特大地震影響窿祥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蝙寨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嗤瞎。 院中可真熱鬧墙歪,春花似錦、人聲如沸贝奇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掉瞳。三九已至毕源,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間陕习,已是汗流浹背霎褐。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留该镣,地道東北人冻璃。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像损合,于是被迫代替她去往敵國(guó)和親省艳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

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

  • 1. 所謂跨域 跨域是一種瀏覽器同源安全策略嫁审,也即瀏覽器單方面限制腳本的跨域訪問跋炕。很多人可能誤認(rèn)為資源跨域時(shí)無法請(qǐng)...
    blurooo閱讀 6,172評(píng)論 11 54
  • CORS是一個(gè)W3C標(biāo)準(zhǔn),全稱是"跨域資源共享"(Cross-origin resource sharing)律适。 ...
    奇特思維家閱讀 1,125評(píng)論 0 3
  • 題目1.什么是同源策略? 同源策略(Same origin Policy): 瀏覽器出于安全方面的考慮辐烂,只允許與本...
    FLYSASA閱讀 1,727評(píng)論 0 6
  • 1. 什么是跨域 跨域,是指瀏覽器不能執(zhí)行其他網(wǎng)站的腳本擦耀。它是由瀏覽器的同源策略造成的棉圈,是瀏覽器對(duì)JavaScri...
    cbw100閱讀 6,341評(píng)論 2 86
  • gank.io 感謝 http://gank.io 提供的api幫助完成這個(gè)app該項(xiàng)目完全開源,單純?yōu)榱藢W(xué)習(xí)與交...
    jzhu085閱讀 316評(píng)論 0 2