關(guān)于跨域

在使用Vue搭建的一個后端管理系統(tǒng)中蝌借,我使用axios請求本地的Node環(huán)境下的接口枯冈,但是請求失敗华坦,然后我錯誤信息是:

331552554043_.pic.jpg

大概意思就是不能訪問http://localhost:8080
我的Vue項目端口是http://localhost:8081撮躁,Node服務(wù)端運(yùn)行在http://localhost:8080端口上实辑,也就是說因?yàn)檎埱蠖丝诤晚憫?yīng)端口不一致捺氢,所以請求失敗。
我也在網(wǎng)上查看了一些關(guān)于跨域出現(xiàn)的原因及解決的方法徙菠,并記錄下來讯沈。

為什么會有跨域

跨域一句話的理解就是:服務(wù)端和請求端的地址不一樣。

什么是跨域

Ajax 的便利性大家都清楚婿奔,可以在不向服務(wù)器提交完整的頁面的情況下缺狠,實(shí)現(xiàn)局部更新頁面。但是瀏覽器處于對安全方面的考慮萍摊,不允許跨域調(diào)用其他頁面的對象挤茄。
其實(shí)這個也不能怪瀏覽器,假設(shè)誰都可以隨隨便便向你發(fā)送請求冰木,那樣有很大的安全隱患穷劈。
根據(jù)瀏覽器的同源策略, 只有當(dāng)協(xié)議,域名踊沸,端口相同的時候才算是同源, 反之則均視為是一個跨域的請求.
也就是說我剛剛的Vue端口是8081歇终,服務(wù)端端口是8080,端口不一樣逼龟,因?yàn)橥床呗缘拇嬖?评凝,所有我的請求會失敗。

一個問題腺律,當(dāng)找到了原因奕短,這個問題就解決了一半了。

怎么解決跨域

下面就先介紹三種跨全域的方法:

JSONP

應(yīng)該是最常見解決跨域的方法了匀钧,
他為什么能解決跨域呢翎碑,是因?yàn)閃eb 頁面上調(diào)用 js 文件不受瀏覽器同源策略的影響,所以通過 Script 便簽可以進(jìn)行跨域的請求:

  1. 首先前端先設(shè)置好回調(diào)函數(shù)之斯,并將其作為 url 的參數(shù)日杈。
  2. 服務(wù)端接收到請求后,通過該參數(shù)獲得回調(diào)函數(shù)名,并將數(shù)據(jù)放在參數(shù)中將其返回
  3. 收到結(jié)果后因?yàn)槭?script 標(biāo)簽达椰,所以瀏覽器會當(dāng)做是3腳本進(jìn)行運(yùn)行翰蠢,從而達(dá)到跨域獲取數(shù)據(jù)的目的。
    我的前端是index.html啰劲,后端是server.js
    后端邏輯:
//server.js
const url = require('url');
const http = require('http');

http.createServer((req, res)=>{
const data = {
    x: 10//返回的數(shù)據(jù)
};
const callback = url.parse(req.url, true).query.callback;
res.writeHead(200);
res.end(`${callback}(${JSON.stringify(data)})`);
//執(zhí)行回調(diào)函數(shù)梁沧,返回data
}).listen(3000, 'localhost');

console.log('啟動服務(wù),監(jiān)聽 localhost:3000');

然后使用node server.js運(yùn)行
前端:

//index.html
<body>
    <script>
    function jsonpCallback(data) {
        console.log('獲得 X 數(shù)據(jù):' + data.x);
    }
    </script>
    <script src="http://localhost:3000?callback=jsonpCallback"></script>
</body>

之后打開index.html;就可以在控制臺看到返回的數(shù)據(jù)了:


341552556856_.pic.jpg

至此蝇裤,通過 JSONP 跨域獲取數(shù)據(jù)已經(jīng)成功了廷支,jsonp這種方法跨域,他的兼容性很好,可以在古老的瀏覽器中國使用,因?yàn)檫@種方法是利用了<script>標(biāo)簽的特殊性行楞,所有只支持GET請求。

CORS

CORS 是一個 W3C 標(biāo)準(zhǔn)施敢,全稱是"跨域資源共享"(Cross-origin resource sharing)它允許瀏覽器向跨源服務(wù)器,發(fā)出 XMLHttpRequest 請求狭莱,從而克服了 ajax 只能同源使用的限制僵娃。

CORS 需要瀏覽器和服務(wù)器同時支持才可以生效,對于開發(fā)者來說腋妙,CORS 通信與同源的 ajax 通信沒有差別默怨,代碼完全一樣。瀏覽器一旦發(fā)現(xiàn) ajax 請求跨源骤素,就會自動添加一些附加的頭信息匙睹,有時還會多出一次附加的請求,但用戶不會有感覺济竹。

因此痕檬,實(shí)現(xiàn) CORS 通信的關(guān)鍵是服務(wù)器。只要服務(wù)器實(shí)現(xiàn)了 CORS 接口送浊,就可以跨源通信谆棺。

前端:

<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
$.ajax({
    url:"http://127.0.0.1:3000",
    success:function(res){
        var res = JSON.parse(res);
        $('body').text(res.data);
        console.log(res.data);
    }
});
</script>

這次前端啟動需要使用node-server來啟動,使用npm install node-server下載罕袋,然后當(dāng)前目錄下使用node-server就可以了
后端:

const http = require('http');

http.createServer((req, res)=>{
const data = {
    'data': 'Hello world'//返回的數(shù)據(jù)
};
res.writeHead(200, {'Access-Control-Allow-Origin': 'http://127.0.0.1:8080'});
//設(shè)置的頭部信息需要和前端請求的地址一致
res.end(JSON.stringify(data));
//返回data
}).listen(3000, '127.0.0.1');

console.log('啟動服務(wù),監(jiān)聽 127.0.0.1:3000');

使用命令node server.js啟動碍岔;

211552638161_.pic_hd.jpg

CORS與JSONP的使用目的相同浴讯,但是比JSONP更強(qiáng)大。

JSONP只支持GET請求蔼啦,CORS支持所有類型的HTTP請求榆纽。JSONP的優(yōu)勢在于支持老式瀏覽器,以及可以向不支持CORS的網(wǎng)站請求數(shù)據(jù)。

Server Proxy

服務(wù)器代理奈籽,顧名思義饥侵,當(dāng)你需要有跨域的請求操作時發(fā)送請求給后端,讓后端幫你代為請求衣屏,然后最后將獲取的結(jié)果發(fā)送給你躏升。

假設(shè)有這樣的一個場景,你的頁面需要獲取 CNode:Node.js專業(yè)中文社區(qū) 論壇上一些數(shù)據(jù)狼忱,如通過 https://cnodejs.org/api/v1/topics膨疏,當(dāng)時因?yàn)椴煌颍阅憧梢詫⒄埱蠛蠖俗昱屍鋵υ撜埱蟠鸀檗D(zhuǎn)發(fā)佃却。

后端代碼如下:

const url = require('url');
const http = require('http');
const https = require('https');

http.createServer((req, res)=>{
const path = url.parse(req.url).path.slice(1);
//核對請求路由是否一致
if(path === 'topics'){
    https.get('https://cnodejs.org/api/v1/topics', (resp)=>{
        //https代發(fā)請求
        let data='';
        resp.on('data', chunk=>{
            data+= chunk
        });
        resp.on('end', ()=>{
            res.writeHead(
                200,
                {'Content-Type': 'application/json; charset=utf-8'}
            );
            res.end(data);
            //返回數(shù)據(jù)
        })
    })
}

}).listen(3000, '127.0.0.1');

console.log('啟動服務(wù),監(jiān)聽 127.0.0.1:3000');

前端代碼:

<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
$.ajax({
    url:"https://cnodejs.org/api/v1/topics",
    success:function(res){
        $('body').text(JSON.stringify(res));
        console.log(res);
    }
});
</script>

這樣就成功了


221552639459_.pic_hd.jpg

總結(jié)

常用的跨域方式基本就是這三種:

  1. JSONP
    優(yōu)點(diǎn)是可以兼容老瀏覽器窘俺,缺點(diǎn)是只能發(fā)送GET請求
  2. CORS
    優(yōu)點(diǎn)簡單方便饲帅,支持post請求,缺點(diǎn)是需要后端的配合,不支持老版瀏覽器瘤泪。灶泵。
  3. Server Proxy
    優(yōu)點(diǎn)是前端正常發(fā)送ajax請求,缺點(diǎn)是后端會二次請求均芽。

其他的跨域方式還有:location.hash丘逸、window.namepostMessage等方式掀宋,有時間也可以了解一下深纲。

參考資料:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末劲妙,一起剝皮案震驚了整個濱河市湃鹊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌镣奋,老刑警劉巖币呵,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異侨颈,居然都是意外死亡余赢,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門哈垢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妻柒,“玉大人,你說我怎么就攤上這事耘分【偎” “怎么了绑警?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長央渣。 經(jīng)常有香客問我计盒,道長,這世上最難降的妖魔是什么芽丹? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任北启,我火速辦了婚禮,結(jié)果婚禮上志衍,老公的妹妹穿的比我還像新娘暖庄。我一直安慰自己,他們只是感情好楼肪,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布培廓。 她就那樣靜靜地躺著,像睡著了一般春叫。 火紅的嫁衣襯著肌膚如雪肩钠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天暂殖,我揣著相機(jī)與錄音价匠,去河邊找鬼。 笑死呛每,一個胖子當(dāng)著我的面吹牛踩窖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播晨横,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼洋腮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了手形?” 一聲冷哼從身側(cè)響起啥供,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎库糠,沒想到半個月后伙狐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瞬欧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年贷屎,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片艘虎。...
    茶點(diǎn)故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡豫尽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出顷帖,到底是詐尸還是另有隱情美旧,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布贬墩,位于F島的核電站榴嗅,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏陶舞。R本人自食惡果不足惜嗽测,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肿孵。 院中可真熱鬧唠粥,春花似錦、人聲如沸停做。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛉腌。三九已至官份,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間烙丛,已是汗流浹背舅巷。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留河咽,地道東北人钠右。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像忘蟹,于是被迫代替她去往敵國和親飒房。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評論 2 361

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