跨域的幾種解決方案

方法一:JSONP

原理

JSONP(JSON with padding)淮椰,padding有填補(bǔ)的意思槐沼,所以JSONP也就是往JSON上加一些東西。在HTML 中 script 標(biāo)簽可以加載其他域下的js,比如我們經(jīng)常引入一個(gè)其他域下線上cdn的jQuery。那么我們可以利用這個(gè)特性來向其他域請求數(shù)據(jù)冈欢。

對于HTML中的script標(biāo)簽,src中請求的數(shù)據(jù)返回后會被當(dāng)做Javascript代碼來運(yùn)行盈简,所以當(dāng)后臺返回?cái)?shù)據(jù)的時(shí)候凑耻,不能直接返回?cái)?shù)組或者字符串之類的,應(yīng)該對數(shù)據(jù)進(jìn)行“包裹”送火,也就是JSONP中的P代表的padding拳话,加點(diǎn)東西。下面請看例子种吸。

舉例

第一步

我們現(xiàn)在向后臺的約定了一個(gè)獲取天氣的接口getWeather弃衍,然后在script標(biāo)簽中寫一個(gè)這樣的請求:
<script src="a.com/getWeather?callback=showData"></script>

第二步

后臺收到/getWeather這個(gè)路由后,應(yīng)該是直接向我返回一個(gè)JSON格式的數(shù)據(jù)坚俗,其中包含天氣镜盯,比如這個(gè)數(shù)據(jù),{ "beijing" : "sunny" }猖败。但對于script標(biāo)簽速缆,返回的數(shù)據(jù)是要作為Javascript代碼執(zhí)行的,上面返回的數(shù)據(jù)應(yīng)該進(jìn)行“包裹”恩闻,例如變成這樣showData( { "beijing" : "sunny" } )艺糜,服務(wù)器端寫法如下:

var http = require('http');
var url = require('url');
var fs = require('fs');
var path = require('path');

var server = http.createServer(function(req,res){
    var pathObj = url.parse(req.url,true);
//處理getWeather請求
if(pathObj.pathname === '/getWeather'){
        var callback = pathObj.query.callback
        console.log(callback)
        res.write(`${callback}({"beijing":"sunny"})`)
        res.end()
    }else{
        res.end()
    }
})
server.listen(8080);

結(jié)果

response

控制臺打印出結(jié)果

方法二:CORS

原理

CORS 全稱是跨域資源共享(Cross-Origin Resource Sharing),是一種 ajax 跨域請求資源的方式幢尚,支持現(xiàn)代瀏覽器破停,IE支持10以上。 實(shí)現(xiàn)方式很簡單尉剩,當(dāng)你使用 XMLHttpRequest 發(fā)送請求時(shí)真慢,瀏覽器發(fā)現(xiàn)該請求不符合同源策略,會給該請求加一個(gè)請求頭:Origin理茎,Origin對應(yīng)的值是當(dāng)前網(wǎng)站的域名黑界。后臺進(jìn)行一系列處理,如果確定接受請求則在返回結(jié)果中加入一個(gè)響應(yīng)頭:Access-Control-Allow-Origin皂林; 瀏覽器判斷該響應(yīng)頭中是否包含 Origin 的值(也就是Access-Control-Allow-Origin的值和Origin的值對應(yīng))朗鸠,如果有則瀏覽器會處理響應(yīng),我們就可以拿到響應(yīng)數(shù)據(jù)础倍,如果不包含童社,瀏覽器直接駁回,這時(shí)我們無法拿到響應(yīng)數(shù)據(jù)著隆。所以 CORS 的表象是讓你覺得它與同源的 ajax 請求沒啥區(qū)別扰楼,代碼完全一樣呀癣。

舉例

  • HTML代碼
//打開此頁面使用的地址是a.com:8080
<!DOCTYPE html>
<html>
<head>
    <title>a.html</title>
    <meta charset="utf-8">
</head>
<body>
    <button id="click">發(fā)送請求</button>
    <script type="text/javascript">
            click.onclick = function(){
            var xhr = new XMLHttpRequest()
            xhr.open('GET', 'http://b.com:8080/getWeather')
            xhr.onload = function(){
                console.log(xhr.responseText)
            }
            xhr.send()
        }   
    </script>
</body>
</html>
  • 服務(wù)端代碼
var http = require('http');
var url = require('url');
var fs = require('fs');
var path = require('path');

var server = http.createServer(function(req,res){
    var pathObj = url.parse(req.url,true);
//處理getWeather請求
if(pathObj.pathname === '/getWeather'){
        var weather = {"beijing":"sunny"}
        res.setHeader('Access-Control-Allow-Origin', 'http://a.com:8080')
        res.write(JSON.stringify(weather))
        res.end()
    }else{
        res.end()
    }
})
server.listen(8080);
Network查看效果

方法三:降域

原理

主要用于頁面上iframe跨域的操作。降域就是通過在兩個(gè)頁面使用 document.domain方法弦赖,將兩個(gè)頁面的域名統(tǒng)一项栏,由此來實(shí)現(xiàn)跨域。不過這要求兩個(gè)頁面的域名有公共的部分蹬竖。

舉例

  • a.html
<!DOCTYPE html>
<html>
<head>
    <title>a.html</title>
    <meta charset="utf-8">
    <style type="text/css">
        .windowB {
            height: 250px;
            width: 500px;
            margin: 10px 10px;
            border: 1px #ccc solid;
        }
    </style>
</head>
<body>
    <h1>this is a.html</h1>
    <iframe class="windowB" src="http://b.common.com:8080/b.html"></iframe>
</body>
</html>
  • b.html
<!DOCTYPE html>
<html>
<head>
    <title>b.html</title>
</head>
<body>
    <h1>this is b.html</h1>
    <script type="text/javascript">
        document.domain = 'common.com'
    </script>
</body>
</html>

效果

控制臺可獲取iframe中信息

方法四:postMessage

原理

當(dāng)前頁面要和iframe進(jìn)行數(shù)據(jù)交互的時(shí)候沼沈,可以選中需要交互的iframe,然后利用postMessage這個(gè)方法向它發(fā)送消息币厕,然后在iframe頁面上監(jiān)聽message這個(gè)事件列另,對發(fā)來的信息做處理,這樣就可以實(shí)現(xiàn)數(shù)據(jù)的交互旦装。

舉例

  • a.html
<!DOCTYPE html>
<html>
<head>
    <title>a.html</title>
    <meta charset="utf-8">
    <style type="text/css">
        .windowB {
            height: 250px;
            width: 500px;
            margin: 10px 10px;
            border: 1px #ccc solid;
        }
    </style>
</head>
<body>
    <h1>this is a.html</h1>
    <button id="click">發(fā)送請求</button>
    <input type="text" name="data" placeholder="請輸入文字">
    <script type="text/javascript">
            function $(e){
                var element = document.querySelector(e)
                return element
            }
//選中input页衙,綁定事件,當(dāng)輸入信息時(shí)阴绢,在iframe中展示店乐,*表示在任何域下都可以接受
            $('input').addEventListener('input', function(){
                window.frames[0].postMessage(this.value,'*')
            })
    </script>
</body>
</html>
  • b.html
<!DOCTYPE html>
<html>
<head>
    <title>b.html</title>
    <meta charset="utf-8">
</head>
<body>
    <h1>this is b.html</h1>
    <input type="text" name="data2" placeholder="顯示數(shù)據(jù)">
    <script type="text/javascript">
         function $(e){
                var element = document.querySelector(e)
                return element
            }
        window.addEventListener('message',function(e){
            $('input').value = e.data
        })
    </script>
</body>
</html>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市呻袭,隨后出現(xiàn)的幾起案子眨八,更是在濱河造成了極大的恐慌,老刑警劉巖左电,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件廉侧,死亡現(xiàn)場離奇詭異,居然都是意外死亡篓足,警方通過查閱死者的電腦和手機(jī)伏穆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纷纫,“玉大人,你說我怎么就攤上這事陪腌∪杩” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵诗鸭,是天一觀的道長染簇。 經(jīng)常有香客問我,道長强岸,這世上最難降的妖魔是什么锻弓? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮蝌箍,結(jié)果婚禮上青灼,老公的妹妹穿的比我還像新娘暴心。我一直安慰自己,他們只是感情好杂拨,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布专普。 她就那樣靜靜地躺著,像睡著了一般弹沽。 火紅的嫁衣襯著肌膚如雪檀夹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天策橘,我揣著相機(jī)與錄音炸渡,去河邊找鬼。 笑死丽已,一個(gè)胖子當(dāng)著我的面吹牛蚌堵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播促脉,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼辰斋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了瘸味?” 一聲冷哼從身側(cè)響起宫仗,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎旁仿,沒想到半個(gè)月后藕夫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡枯冈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年毅贮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尘奏。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡滩褥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出炫加,到底是詐尸還是另有隱情瑰煎,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布俗孝,位于F島的核電站酒甸,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏赋铝。R本人自食惡果不足惜插勤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧农尖,春花似錦析恋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至窟扑,卻和暖如春喇颁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嚎货。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工橘霎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人殖属。 一個(gè)月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓姐叁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親洗显。 傳聞我的和親對象是個(gè)殘疾皇子外潜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

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