跨域的解決方式

jsonp

html中可以通過(guò)script標(biāo)簽引入其他域的js,利用這一特性,結(jié)合后端支持,可以實(shí)現(xiàn)跨域訪問(wèn)接口
實(shí)現(xiàn)原理:

  1. 定義數(shù)據(jù)處理函數(shù)_fun
  2. 創(chuàng)建script標(biāo)簽,src的地址執(zhí)行后端接口,最后加個(gè)參數(shù)callback=fun
  3. 服務(wù)端在收到請(qǐng)求后,解析參數(shù),計(jì)算返還數(shù)據(jù),輸出 fun(data) 字符串。
  4. fun(data)會(huì)放到script標(biāo)簽做為js執(zhí)行。此時(shí)會(huì)調(diào)用fun函數(shù),將data做為參數(shù)。

前端代碼:

<div class="query-area">
        <input type="text" name="username" value="hunger" placeholder="hunger, ruoyu, anyone">
        <button>查詢朋友</button>   
    </div>
    <div class="detail-area">
        <ul>     
        </ul>
    </div>
    <script>
        var btn = document.querySelector('.query-area button');
        var input = document.querySelector('.query-area input');
        btn.addEventListener('click', function(){
        var script=document.createElement("script");
        script.src="http://a.test.com:8080/getFriends?username="+input.value+"&callback=render";
        document.head.appendChild(script);
        document.head.removeChild(script);
        });
        function render(friends){
        var detailCt = document.querySelector('.detail-area ul');
        detailCt.innerHTML = '';
        var ct = document.createDocumentFragment();
        for(var i = 0; i < friends.length; i++){
            var node = document.createElement('li');
            node.innerText = friends[i];
            ct.appendChild(node)
        }
        detailCt.appendChild(ct)
        }
    </script>

后臺(tái)代碼:

router.get('/getFriends', function(req, res) {
        var username = req.query.username ;// 通過(guò) req.query獲取請(qǐng)求參數(shù)
        var friends;
    
    //根據(jù)請(qǐng)求參數(shù)mock數(shù)據(jù)
    switch (username){
        case 'ruoyu':
            friends = ['小米', '小剛'];
            break;
        case 'hunger':
            friends = ['小谷', '小花'];
            break;
        default:
            friends = ['沒(méi)有朋友'];
    }
    var cb=req.query.callback;
    res.send(cb+'('+JSON.stringify(friends)+')')
    });

CORS

CORS 全稱是跨域資源共享(Cross-Origin Resource Sharing),是一種 ajax 跨域請(qǐng)求資源的方式,支持現(xiàn)代瀏覽器,IE支持10以上。
實(shí)現(xiàn)方式:

  1. 使用XMLHttpRequest發(fā)送請(qǐng)求時(shí),服務(wù)器發(fā)現(xiàn)不同源會(huì)在請(qǐng)求中加一個(gè)請(qǐng)求頭Origin
  2. 后臺(tái)確定接受該請(qǐng)求,則在響應(yīng)頭中加一個(gè)Access-Control-Allow-Origin
  3. 瀏覽器判斷該響應(yīng)頭中包含origin則響應(yīng)請(qǐng)求,沒(méi)有不響應(yīng)

前端代碼:

    <div class="query-area">
        <input type="text" name="username" value="hunger" placeholder="hunger, ruoyu, anyone">
        <button>查詢朋友</button>   
    </div>
    <div class="detail-area">
        <ul>     
        </ul>
    </div>

    <script>
        var btn = document.querySelector('.query-area button');
        var input = document.querySelector('.query-area input');
    
        btn.addEventListener('click', function(){
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function(){
            if(xhr.readyState === 4 && (xhr.status === 200 || xhr.status === 304)){
            var friends = JSON.parse(xhr.responseText);
            render(friends)
            }
        };
            xhr.open('get', 'http://a.test.com:8080/getFriends?username=' + input.value, true);
            xhr.send();
        });
        function render(friends){
        var detailCt = document.querySelector('.detail-area ul');
        detailCt.innerHTML = '';
        var ct = document.createDocumentFragment();
        for(var i = 0; i < friends.length; i++){
            var node = document.createElement('li');
            node.innerText = friends[i];
            ct.appendChild(node)
        }
        detailCt.appendChild(ct)
        }
    </script>

后臺(tái)代碼:

    router.get('/getFriends', function(req, res) {
        var username = req.query.username ;// 通過(guò) req.query獲取請(qǐng)求參數(shù)
        var friends;
    //根據(jù)請(qǐng)求參數(shù)mock數(shù)據(jù)
    switch (username){
        case 'ruoyu':
            friends = ['小米', '小剛'];
            break;
        case 'hunger':
            friends = ['小谷', '小花'];
            break;
        default:
            friends = ['沒(méi)有朋友'];
    }
        res.header("Access-Control-Allow-Origin", "http://b.test.com:8080");
        res.send(friends);
    });

降域

降域的使用條件是兩個(gè)名的一級(jí)域名相同(例如: a.test.com 與 b.test.com)都同屬于test.com這個(gè)域名

測(cè)試時(shí)需使用a.test.com:8080/a.html訪問(wèn),不能使用localhost,否則會(huì)報(bào)錯(cuò):報(bào)錯(cuò)信息為不能把domain設(shè)置為test.com

a.html

    <html>
    <style>
        .ct {
            width: 910px;
            margin: auto;
        }
        
        .main {
            float: left;
            width: 450px;
            height: 300px;
            border: 1px solid #ccc;
        }
        
        .main input {
            margin: 20px;
            width: 200px;
        }
        
        .iframe {
            float: right;
        }
        
        iframe {
            width: 450px;
            height: 300px;
            border: 1px dashed #ccc;
        }
    </style>

    <div class="ct">
        <h1>使用降域?qū)崿F(xiàn)跨域</h1>
        <div class="main">
            <input type="text" placeholder="http://a.test.com:8080/a_jiangyu.html">
        </div>

        <iframe src="http://b.test.com:8080/b_jiangyu.html" frameborder="0"></iframe>

    </div>


    <script>
        //URL: http://a.jrg.com:8080/a.html
        document.querySelector('.main input').addEventListener('input', function() {
            console.log(this.value);
            window.frames[0].document.querySelector('input').value = this.value;
        })

        //取一級(jí)域名作為domain
        document.domain = "test.com"
    </script>

    </html>

b.html

    <html>
    <style>
        html,
        body {
            margin: 0;
        }
        
        input {
            margin: 20px;
            width: 200px;
        }
    </style>

    <input id="input" type="text" placeholder="http://b.jiangyu.com:8080/b.html">
    <script>
        // URL: http://b.jrg.com:8080/b.html

        document.querySelector('#input').addEventListener('input', function() {
            window.parent.document.querySelector('input').value = this.value;
        })

        //取一級(jí)域名作為domain
        document.domain = 'test.com';
    </script>

    </html>

PostMessage

使用window.postMessage() 實(shí)現(xiàn)
postMessage的原理是會(huì)向另一個(gè)地方發(fā)送信息,另一個(gè)地方通常是iframe,或者是由當(dāng)前頁(yè)面彈出的窗口。參數(shù)是:信息以及表示接受消息方的來(lái)自哪個(gè)域的字符串,如果給定*便是不限定接受者的域。

a.html

    <html>
    <style>
        .ct {
            width: 910px;
            margin: auto;
        }
        
        .ct h1 {
            text-align: center;
        }
        
        .main {
            float: left;
            width: 450px;
            height: 300px;
            border: 1px solid #ccc;
        }
        
        .main input {
            margin: 20px;
            width: 200px;
        }
        
        .iframe {
            float: right;
        }
        
        iframe {
            width: 450px;
            height: 300px;
            border: 1px dashed #ccc;
        }
    </style>

    <div class="ct">
        <h1>使用postMessage實(shí)現(xiàn)跨域</h1>
        <div class="main">
            <input type="text" placeholder="http://a.test.com:8080/a.html">
        </div>

        <iframe src="http://localhost:8080/b.html" frameborder="0"></iframe>

    </div>


    <script>
        //URL: http://a.test.com:8080/a.html
        $('.main input').addEventListener('input', function() {
            window.frames[0].postMessage(this.value, '*');
        })
        window.addEventListener('message', function(e) {
            $('.main input').value = e.data
        });

        function $(id) {
            return document.querySelector(id);
        }
    </script>

    </html>

b.html

    <html>
    <style>
        html,
        body {
            margin: 0;
        }
        
        input {
            margin: 20px;
            width: 200px;
        }
    </style>

    <input id="input" type="text" placeholder="http://b.test.com:8080/b.html">
    <script>
        // URL: http://b.test.com:8080/b.html

        $('#input').addEventListener('input', function() {
            window.parent.postMessage(this.value, '*');
        })
        window.addEventListener('message', function(e) {
            $('#input').value = e.data
        });

        function $(id) {
            return document.querySelector(id);
        }
    </script>

    </html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評(píng)論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,441評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 178,211評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 63,736評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,475評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 55,834評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 43,009評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,559評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,516評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,728評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 35,132評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 36,443評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,249評(píng)論 3 399
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,484評(píng)論 2 379

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

  • 跨域有很多種方式,下面就簡(jiǎn)單說(shuō)說(shuō)跨域最常見(jiàn)的幾種解決方式1、JSONPJSONP是服務(wù)器與客戶端跨源通信的常用方法...
    小囧兔閱讀 405評(píng)論 0 0
  • jsonp html中可以通過(guò)script標(biāo)簽引入其他域的js,利用這一特性,結(jié)合后端支持,可以實(shí)現(xiàn)跨域訪問(wèn)接口實(shí)...
    madpluto閱讀 308評(píng)論 0 0
  • JSONP JSONP(JSON with Padding)是資料格式JSON的一種“使用模式”,可以讓網(wǎng)頁(yè)從別的...
    阿魯提爾閱讀 221評(píng)論 0 0
  • 說(shuō)實(shí)話,比起好韋躍的小說(shuō),更喜歡他的把妹達(dá)人教程,順帶著對(duì)以前從來(lái)不關(guān)注的情感專欄也有了試試看的想法(當(dāng)然這之間沒(méi)...
    無(wú)聲遠(yuǎn)望閱讀 2,231評(píng)論 4 13
  • 你就把氣流擰開(kāi) 這樣我隔著氤氳 暈眩地暫時(shí)性失明 看不清你的眼瞼 氣候脅迫他的妻子溫度 一起多變 不會(huì)收斂 耳光扇...
    CastorPak閱讀 333評(píng)論 2 10