欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

通過一篇文章由淺入深的理解JSONP并拓展

 更新時(shí)間:2022年01月23日 10:40:15   作者:K0rz3n  
這篇文章主要給大家介紹了關(guān)于理解JSONP并拓展的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

簡單描述

JSONP 是 JSON with padding(填充式 JSON 或參數(shù)式 JSON)的簡寫。
JSONP實(shí)現(xiàn)跨域請(qǐng)求的原理簡單的說,就是動(dòng)態(tài)創(chuàng)建<script>標(biāo)簽,然后利用<script>的src 不受同源策略約束來跨域獲取數(shù)據(jù)。

JSONP 由兩部分組成:回調(diào)函數(shù)數(shù)據(jù)?;卣{(diào)函數(shù)是當(dāng)響應(yīng)到來時(shí)應(yīng)該在頁面中調(diào)用的函數(shù)?;卣{(diào)函數(shù)的名字一般是在請(qǐng)求中指定的。而數(shù)據(jù)就是傳入回調(diào)函數(shù)中的 JSON 數(shù)據(jù)。

動(dòng)態(tài)創(chuàng)建<script>標(biāo)簽,設(shè)置其src,回調(diào)函數(shù)在src中設(shè)置:

var script = document.createElement("script");
script.src = "https://api.douban.com/v2/book/search?q=javascript&count=1&callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);

在頁面中,返回的JSON作為response參數(shù)傳入回調(diào)函數(shù)中,我們通過回調(diào)函數(shù)來來操作數(shù)據(jù)。

function handleResponse(response){
    // 對(duì)response數(shù)據(jù)進(jìn)行操作代碼
}

上面是簡單直接的對(duì)JSONP 的描述,可能有些人不是很懂,我們下面一步一步分析

層層深入

先通過一個(gè)簡單的實(shí)例簡單的理解一下同源策略的作用

首先我們?cè)诒镜貙懭?/p>

1.html

<!DOCTYPE html>
<html>
<head>
    <title>GoJSONP</title>
</head>
<body>
<script type="text/javascript">
    function jsonhandle(data){
        alert("age:" + data.age + "name:" + data.name);
    }
</script>
<script type="text/javascript" src="jquery-3.3.1.min.js">
</script>
<script type="text/javascript">
    $(document).ready(function(){
        $.ajax({
            type : "get",
            url : "http://check.k0rz3n.com/test.php?id=1",
            dataType: "jsonp",//指定我們的請(qǐng)求是一個(gè) jsonp 的請(qǐng)求
            success : function(data) {//success 指定的是默認(rèn)的回調(diào)函數(shù)
                jsonhandle(data);
            }

        });
    });
</script>
</body>
</html>

我服務(wù)器上的test.php會(huì)返回json 格式的數(shù)據(jù)給客戶端

test1.php

<?php
header('Content-Type:application/json; charset=utf-8');
$data = array('age'=>19,'name'=>'jianshu');
exit(json_encode($data));
?>

如果正常訪問的話,那么我們的瀏覽器應(yīng)該會(huì)彈出對(duì)話框,結(jié)果我們會(huì)得到這樣的結(jié)果

此處輸入圖片的描述

可以看到,瀏覽器發(fā)現(xiàn)這是一個(gè)跨域的請(qǐng)求,但是他在服務(wù)器的返回頭中缺沒有發(fā)現(xiàn)
Access-Control-Allow-Origin 值允許 http://localhost 的訪問,于是就攔截了。

也就是說,雖然瀏覽器受到了同源策略的限制,不允許實(shí)現(xiàn)跨域訪問,但是由于在開發(fā)過程中前后端的交互過程中不可避免地會(huì)涉及到跨域的請(qǐng)求(設(shè)計(jì)同源策略的人想必也發(fā)現(xiàn)了這個(gè)問題),于是設(shè)計(jì)者給我們留了一個(gè)后門,就是只要服務(wù)器響應(yīng)頭中返回允許這個(gè)源的選項(xiàng),那么跨域請(qǐng)求就會(huì)成功。(這里糾正一個(gè)誤區(qū),不要認(rèn)為瀏覽器默認(rèn)支持同源策略就意味著不同源的請(qǐng)求就不能發(fā)出去,其實(shí)還是能發(fā)出去的,只是要看響應(yīng)頭而已。)

我們知道在頁面中有幾個(gè)東西是對(duì)同源策略免疫的,那就是 <img> 的src 、<link> 的 href 還有就是<script>的 src , JSONP 就是利用 script 標(biāo)簽的sec 屬性實(shí)現(xiàn)跨區(qū)域請(qǐng)求的

script標(biāo)簽的請(qǐng)求不論是不是同源一律不受同源策略的限制,那我們就找到了解決跨域訪問的方法(似乎這個(gè)方法一開始就存在…..)

我們改變一下代碼,本地直接通過script標(biāo)簽請(qǐng)求服務(wù)器上的js,js 的內(nèi)容就是調(diào)用參數(shù)已經(jīng)傳進(jìn)去的本地的js函數(shù)

2.html

<!DOCTYPE html>
<html>
<head>
    <title>GoJSONP</title>
</head>
<body>
<script type="text/javascript">
    function jsonhandle(data){
        alert("age:" + data.age + "name:" + data.name);
    }
</script>
<script type="text/javascript" src="jquery-3.3.1.min.js">
</script>
<script type="text/javascript" src="http://check.k0rz3n.com/remote.js"></script>
</body>
</html>

remote.js

jsonhandle({
    "age" : 15,
    "name": "John",
})

注意:

(1)遠(yuǎn)程的js 代碼不需要script標(biāo)簽
(2)這其實(shí)也給了我們一些啟示,就是我們使用 callback 函數(shù)請(qǐng)求的頁面實(shí)際上類型是javascript 的類型,我們可以在這里看一下瀏覽器會(huì)將哪些類型當(dāng)做 javascript 解析:https://mathiasbynens.be/demo/javascript-mime-type

下圖可以看到我們成功利用<script>實(shí)現(xiàn)了跨域的訪問。

此處輸入圖片的描述

那JSONP和這個(gè)有啥關(guān)系,感覺已經(jīng)實(shí)現(xiàn)跨域了還沒有提到一點(diǎn)JSONP,上面說JSONP是基于script標(biāo)簽的,個(gè)人感覺JSONP的優(yōu)勢就是能夠?qū)崿F(xiàn)呢比較方便的函數(shù)選擇,傳一個(gè)參數(shù)就行了,不用像直接調(diào)用那樣必須要換js文件。

真相浮現(xiàn)

先用下面的代碼模擬jsonp的調(diào)用過程方便大家更好的理解jsonp的運(yùn)行過程

3.html

<!DOCTYPE html>
<html>
<head>
    <title>GoJSONP</title>
</head>
<body>
<script type="text/javascript">
    function jsonhandle(data){
        alert("age:" + data.age + "name:" + data.name);
    }
</script>
<script type="text/javascript" src="jquery-3.3.1.min.js">
</script>
<script type="text/javascript">
    $(document).ready(function(){
        var url = "http://check.k0rz3n.com/test1.php?id=1&callback=jsonhandle";
        var obj = $('<script><\/script>');
        obj.attr("src",url);
        $("body").append(obj);
    });
</script>
</body>
</html>

test1.php

<?php
$data = array(
    'age' => 20,
    'name' => 'dada',
);

$callback = $_GET['callback'];

echo $callback."(".json_encode($data).")";
return;

我們?cè)趕cipt標(biāo)簽里面給出的鏈接是我遠(yuǎn)程服務(wù)器的一個(gè)php的代碼,我給這個(gè)文件傳遞了一個(gè)參數(shù),作為我要調(diào)用的函數(shù)。服務(wù)器接收到這個(gè)參數(shù)以后把它當(dāng)做函數(shù)名,并給這個(gè)函數(shù)傳遞了一個(gè)json的值作為用戶調(diào)用的函數(shù)的參數(shù),最終實(shí)現(xiàn)調(diào)用

下面是調(diào)用成功的截圖

實(shí)際上,jquery 給我們提供了現(xiàn)成的接口,我們可以不用這么麻煩

4.html

<!DOCTYPE html>
<html>
<head>
    <title>GoJSONP</title>
</head>
<body>
<script type="text/javascript" src="jquery-3.3.1.min.js"></script>
<script type="text/javascript">
function jsonhandle(data){
    alert("age:" + data.age + "name:" + data.name);
}
</script>
<script type="text/javascript">
    $(document).ready(function(){
        $.ajax({
            type : "get",
            url : "http://check.k0rz3n.com/test1.php?id=1",
            dataType: "jsonp",
            jsonp:"theFunction", //指定回調(diào)函數(shù)在 URL 中的參數(shù)名(不指定默認(rèn)為 callback)
            jsonpCallback: "jsonhandle",//指定回調(diào)函數(shù)名稱(如果不指定,服務(wù)器會(huì)隨機(jī)分配一個(gè)jQueryxxx 的名字)
            success : function(data) {
                console.info("調(diào)用success");
            }

        });
    });
</script>
</body>
</html>

這時(shí)候的請(qǐng)求的 URL 就像下面這個(gè)樣子:

http://check.k0rz3n.com/test1.php?id=1&theFunction=jsonhandle

服務(wù)器端頁面為:

test2.php

<?php
$data = array(
    'age' => 20,
    'name' => 'dada',
);

$callback = $_GET['theFunction'];

echo $callback."(".json_encode($data).")";
return;

怎么樣,大概理解了吧,其實(shí)可以用一個(gè)非常形象的例子說明:

幼稚園吃午飯,小明吧貼有自己名字的碗(回調(diào)函數(shù))給了幼稚園阿姨(服務(wù)器),阿姨給小明盛好飯(json參數(shù))以后又把碗還給了小明。

就是這樣的一個(gè)過程。

相關(guān)拓展:JSONP攻擊

1.JSONP 跨域劫持

實(shí)際上就是由于服務(wù)器端對(duì)JSONP 的請(qǐng)求來源的檢查不嚴(yán)格導(dǎo)致的

攻擊者模擬用戶向有漏洞的服務(wù)器發(fā)送JSONP請(qǐng)求,然后就獲取到了用戶的某些信息,再將這些信息發(fā)送到攻擊者可控的服務(wù)器

2.JSONP 跨域劫持token 實(shí)現(xiàn)CSRF

通過 jsonp 發(fā)起請(qǐng)求,得到泄露的 csrf_token 然后,利用這個(gè)token 實(shí)現(xiàn)CSRF 攻擊

3.Referer 頭的繞過

在攻擊過程中可能會(huì)涉及到 referer 頭的繞過

  • data:URL
    為了逃避他的檢測我們可以選擇不發(fā)送referer這個(gè)頭,那么怎么做呢?這就涉及到 data:URL 頭

為了構(gòu)造一個(gè)不帶HTTP Referer的請(qǐng)求,我們可以濫用data URI方案。因?yàn)槲覀冋谔幚淼拇a包含了引號(hào),雙引號(hào),以及其他一些被阻止的語句,接著使用base64編碼我們的payload(回調(diào)函數(shù)定義以及腳本包含)

data:text/plain;base64our_base64_encoded_code:

以下3個(gè)HTML標(biāo)簽允許我們使用data URI方案:

iframe (在src屬性中) – Internet Explorer下不工作
embed (在src屬性中) – Internet Explorer及Microsoft Edge下不工作
object (在data屬性中) – Internet Explorer及Microsoft Edge下不工作

2.從HTTPS向HTTP發(fā)起請(qǐng)求

如果目標(biāo)網(wǎng)站可以通過HTTP訪問,也可以通過將我們的代碼托管在一個(gè)HTTPS頁面來避免發(fā)送HTTP Referer。如果我們從HTTPS頁面發(fā)起一個(gè)HTTP請(qǐng)求,瀏覽器為了防止信息泄漏是不會(huì)發(fā)送Referer header。以上我們要將惡意代碼托管在一個(gè)啟用了HTTPS的站點(diǎn)。

注意:由于mixed-content安全機(jī)制,在瀏覽器默認(rèn)設(shè)置下是不會(huì)工作的。需要受害者手動(dòng)允許瀏覽器發(fā)出的安全警告。

參考鏈接

  • https://blog.csdn.net/u011897301/article/details/52679486
  • https://blog.csdn.net/u014607184/article/details/52027879
  • http://www.91ri.org/13407.html
  • http://www.freebuf.com/articles/web/70025.html
  • http://www.freebuf.com/articles/web/126347.html
  • https://www.cnblogs.com/chiangchou/p/jsonp.html

總結(jié)

到此這篇關(guān)于JSONP拓展的文章就介紹到這了,更多相關(guān)理解JSONP并拓展內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論