WEB前端跨域知識(shí)總結(jié)—JSONP

一、前言

  • 初識(shí)

XMLHttpRequest cannot load xxxx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'xxxx' is therefore not allowed access. The response had HTTP status code 404.

timg.jpg
  • 什么跨域?
    簡(jiǎn)述:由于瀏覽器XMLHttpRequest同源策略(域名、端口、協(xié)議必須全一致)影響,禁止使用XHR對(duì)象向不同源服務(wù)器發(fā)起HTTP請(qǐng)求。
  • 為啥禁止跨域?
    簡(jiǎn)述:AJAX(XMLHttpRequest)同源策略主要用來(lái)防止CSRF攻擊。我們發(fā)起的每一次HTTP請(qǐng)求都會(huì)帶上請(qǐng)求地址對(duì)應(yīng)的cookie,簡(jiǎn)單來(lái)說(shuō)就是“模仿用戶”訪問“目標(biāo)網(wǎng)站”。
  • 如何解決跨域?
    簡(jiǎn)述:解決跨域問題的方案有很多,例如JSONP、CROS、反向代理等等。
  • 今天我們就一起學(xué)習(xí)下,JSONP跨域解決方案的具體原理,以及實(shí)現(xiàn)封裝一個(gè)自己的jsonp.js。

二、JSONP

大家都知道頁(yè)面中,圖片(img)是可引用外部的,js腳本文件(script)也可引入外部的,所以基本原理就是通過(guò)動(dòng)態(tài)創(chuàng)建script標(biāo)簽,然后利用src屬性進(jìn)行跨域。

1. 基本原理
<body>
<script>
    function fn1(str) { alert('我是fn1:'+ str) }
</script>
<script>
    fn1('下面調(diào)用')
</script>
</body>

總結(jié):上面代碼想必大家都知道結(jié)果吧。會(huì)彈出“我是fn1:下面調(diào)用”

2. 百度搜索api簡(jiǎn)單使用

百度搜索的接口: https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=abc&cb=show

<script>
   function fn1(url){
        window.show = function(json){
            console.log(json);
        } 
        var oS = document.createElement('script');
        oS.src = url;
        document.head.appendChild(oS);
    }
    
    fn1('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=abc&cb=show');
</script>

結(jié)果如下圖所示


總結(jié):從上圖我們可以看出“abc”關(guān)鍵字的搜索結(jié)果可以展示了。也就是解決了跨域問題。

遺留問題:
    1. 創(chuàng)建的script標(biāo)簽,用完是不是需要?jiǎng)h除?
    1. 關(guān)鍵字(此處搜索內(nèi)容)是不是可以靈活進(jìn)行自定義?
    1. 等等
JSONP方法完善以及封裝
function json2url(json){
    var arr = [];
    for(var name in json){
        arr.push(name+'='+json[name]);
    }
    return arr.join('&');
}
/*
** @jsonp               jsonp跨域交互
** @params      
**                      [object]
*/
function jsonp(json){
    //參數(shù)初始值
    json = json||{};
    if(!json.url)return;
    //回調(diào)名字
    json.cbName = json.cbName||'cb';
    //超時(shí)時(shí)間(ms)
    json.timeout =json.timeout||15000;
    //提交數(shù)據(jù)
    json.data = json.data||{};
    //回調(diào)函數(shù)的名字(解決了緩存問題)
    json.data[json.cbName] = 'show'+Math.random();
    //把回調(diào)函數(shù)名字中的.去掉。
    json.data[json.cbName] = json.data[json.cbName].replace('.','');
    //網(wǎng)絡(luò)超時(shí)
    json.timer = setTimeout(function(){
        window[json.data[json.cbName]] = function(){
            oHead.removeChild(oS);
            json.error&&json.error('親,網(wǎng)絡(luò)不給力');
        };
    },json.timeout);
    //定義回調(diào)函數(shù)(全局的)
    window[json.data[json.cbName]] = function(result){
        //把網(wǎng)絡(luò)超時(shí)干掉
        clearTimeout(json.timer);
        //需要把script刪除
        oHead.removeChild(oS);
        //執(zhí)行成功回調(diào)函數(shù)
        json.success&&json.success(result);
    };
    //獲取head標(biāo)簽。
    var oHead = document.getElementsByTagName('head')[0];
    //動(dòng)態(tài)創(chuàng)建script
    var oS = document.createElement('script');
    //給script加src
    oS.src = json.url+'?'+json2url(json.data);
    //把script插入到head標(biāo)簽中
    oHead.appendChild(oS);
}
最后編輯于
?著作權(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ù)。

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