国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

jsonp 跨域原理分析

scq000 / 2115人閱讀

摘要:為請(qǐng)求指定一個(gè)回調(diào)函數(shù)名。這主要用來(lái)讓生成一個(gè)獨(dú)特的函數(shù)名,這樣管理請(qǐng)求更容易,也能方便地提供回調(diào)函數(shù)和錯(cuò)誤處理。在回調(diào)函數(shù)中,通常我們只需通過(guò)判斷請(qǐng)求是否完成,如果已完成,再根據(jù)判斷是否是一個(gè)成功的響應(yīng)。

本篇文章借鑒自 博客園文章
原文地址

AJAX即“Asynchronous Javascript And XML”(異步JavaScript和XML),是指一種創(chuàng)建交互式網(wǎng)頁(yè)應(yīng)用的網(wǎng)頁(yè)開發(fā)技術(shù)。

AJAX 的出現(xiàn)使得網(wǎng)頁(yè)可以通過(guò)在后臺(tái)與服務(wù)器進(jìn)行少量數(shù)據(jù)交換,實(shí)現(xiàn)網(wǎng)頁(yè)的局部刷新。

但是出于安全的考慮,ajax不允許跨域通信(瀏覽器同源策略)。
如果嘗試從不同的域請(qǐng)求數(shù)據(jù),就會(huì)出現(xiàn)錯(cuò)誤(跨域錯(cuò)誤)。
在實(shí)際開發(fā)中,往往需要進(jìn)行跨于請(qǐng)求,這時(shí)要怎么辦呢?

關(guān)于ajax跨域請(qǐng)求?

1、Ajax為什么不能跨域?到底是卡在哪個(gè)環(huán)節(jié)了?。 (請(qǐng)求成功了,但客戶端瀏覽器拿不到請(qǐng)求結(jié)果)

Ajax其實(shí)就是向服務(wù)器發(fā)送一個(gè)GET或POST請(qǐng)求,然后取得服務(wù)器響應(yīng)結(jié)果,返回客戶端。

理論上這是沒(méi)有任何問(wèn)題的,然而普通ajax跨域請(qǐng)求,在服務(wù)器端不會(huì)有任何問(wèn)題,只是服務(wù)端響應(yīng)數(shù)據(jù)返回給瀏覽器的時(shí)候,

瀏覽器根據(jù)響應(yīng)頭的Access-Control-Allow-Origin字段的值來(lái)判斷是否有權(quán)限獲取數(shù)據(jù),

一般情況下,服務(wù)器端如果沒(méi)有在這個(gè)字段做特殊處理的話,跨域是沒(méi)有權(quán)限訪問(wèn)的,所以響應(yīng)數(shù)據(jù)被瀏覽器給攔截了,

所以在ajax回調(diào)函數(shù)里是獲取不到數(shù)據(jù)的。所以現(xiàn)在ajax跨域的問(wèn)題可以轉(zhuǎn)化為數(shù)據(jù)怎么拿回客戶端的問(wèn)題。

2、 html的script標(biāo)簽,img標(biāo)簽,iframe標(biāo)簽,可以請(qǐng)求第三方的資源(不受同源策略影響)

web頁(yè)面可以加載放在任意站點(diǎn)的js、css、圖片等資源,不會(huì)受到"跨域"的影響。

這個(gè)時(shí)候,我們會(huì)想到:既然我們可以調(diào)用第三方站點(diǎn)的js,那么如果我們將數(shù)據(jù)放到第三方站點(diǎn)的js中不就可以將數(shù)據(jù)帶到客戶端了嗎?
JSONP

1、什么是JSONP?

JSONP(JSON with Padding(填充))是JSON的一種“使用模式”,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問(wèn)的問(wèn)題。

其核心思想是利用JS標(biāo)簽里面的跨域特性進(jìn)行跨域數(shù)據(jù)訪問(wèn),
在JS標(biāo)簽里面存在的是一個(gè)跨域的URL,實(shí)際執(zhí)行的時(shí)候通過(guò)這個(gè)URL獲得一段字符串,
這段返回的字符串必須是一個(gè)合法的JS調(diào)用,通過(guò)EVAL這個(gè)字符串來(lái)完成對(duì)獲得的數(shù)據(jù)的處理。

即: 

JSONP是一個(gè)非官方的協(xié)議,它允許在服務(wù)器端集成Script tags返回至客戶端,
通過(guò)javascript callback的形式實(shí)現(xiàn)跨域訪問(wèn)(這僅僅是JSONP簡(jiǎn)單的實(shí)現(xiàn)形式)。

2、JSONP的粗糙實(shí)現(xiàn)

下面我們通過(guò)一個(gè)例子來(lái)說(shuō)明一下JSONP是如何實(shí)現(xiàn)ajax跨域請(qǐng)求的。

html 代碼



    
    Title


    
jsonp
遠(yuǎn)程的getdata.js
getremotedata({
    code:0,
    result:"success"
});

得到的結(jié)果:

jsonp前端及后臺(tái)php的寫法

html代碼還是和上面一樣,只要改變 url就可以了
url= "localhsot:8080/search.php?callback=getremotedata"

后臺(tái) php 代碼
    

看到這里清楚了吧,就是第三方站點(diǎn)生成一個(gè)對(duì)回調(diào)函數(shù)的調(diào)用,傳入查詢結(jié)果,
然后通過(guò)

jquery 封裝在 ajax方法 里面的jsonp

jquery 是如何把 jsonp 封裝到ajax里面的?

一般情況下jqury 生成的訪問(wèn) 遠(yuǎn)程站點(diǎn)的 url
默認(rèn)情況下:(我所在的實(shí)際項(xiàng)目中的使用)

http://web.k3k.net/haila3/pt/tp/index.php/Home/User/getusergoto/?callback=jQuery191028614189839964865_1497261919344&token=420171c8-031a58667e64&_=1497261919346

上述代碼請(qǐng)求生成的url(設(shè)置 jsonpCallback的值為 GetData

http://web.k3k.net/haila3/pt/tp/index.php/Home/User/getusergoto/?callback=GetData&token=420171c8-00b8-031a58667e64&_=1497261919346

最后 一個(gè) _=1497261919346 k v 是為了防止瀏覽器緩存,而由 jquery 自動(dòng)增加上的。

所以相當(dāng)于 在 前端文件中引入了 一個(gè)這樣的js文件

這里有2個(gè)重要的參數(shù)

jsonp
在一個(gè)jsonp請(qǐng)求中重寫回調(diào)函數(shù)的名字。這個(gè)值用來(lái)替代在"callback=?"這種GET或POST請(qǐng)求中URL參數(shù)里的"callback"部分,
比如{jsonp:"onJsonPLoad"}會(huì)導(dǎo)致將"onJsonPLoad=?"傳給服務(wù)器。

jsonpCallback
為jsonp請(qǐng)求指定一個(gè)回調(diào)函數(shù)名。這個(gè)值將用來(lái)取代jQuery自動(dòng)生成的隨機(jī)函數(shù)名。
這主要用來(lái)讓jQuery生成一個(gè)獨(dú)特的函數(shù)名,這樣管理請(qǐng)求更容易,也能方便地提供回調(diào)函數(shù)和錯(cuò)誤處理。

你也可以在想讓瀏覽器緩存GET請(qǐng)求的時(shí)候,指定這個(gè)回調(diào)函數(shù)名。

從jQuery 1.5開始,你也可以使用一個(gè)函數(shù)作為該參數(shù)設(shè)置,在這種情況下,該函數(shù)的返回值就是jsonpCallback的結(jié)果。

通過(guò)一開始 jsonp 原理的分析,可以得出:

當(dāng)我們正常地請(qǐng)求一個(gè)JSON數(shù)據(jù)的時(shí)候,服務(wù)端返回的是一串JSON類型的數(shù)據(jù)。
而我們使用JSONP模式來(lái)請(qǐng)求數(shù)據(jù)的時(shí)候,服務(wù)端返回的是一段可執(zhí)行的JavaScript代碼

所以我們可見(jiàn)服務(wù)器代碼最后一行

echo $_GET["$callback"])."(". json_encode({code:0,msg:"success"}) .")";

就是執(zhí)行的 getdata,然后把數(shù)據(jù)通過(guò)回調(diào)的方式傳遞過(guò)去

OK,就是整個(gè)流程就是:

客戶端發(fā)送一個(gè)請(qǐng)求,規(guī)定一個(gè)可執(zhí)行的函數(shù)名
(這里就是jQuery做了封裝的處理,自動(dòng)幫你生成回調(diào)函數(shù)并把數(shù)據(jù)取出來(lái)供success屬性方法來(lái)調(diào)用,不是傳遞的一個(gè)回調(diào)句柄),
服務(wù)端接受了這個(gè) getdata 函數(shù)名,然后把數(shù)據(jù)通過(guò)實(shí)參的形式發(fā)送出去

以上是 jquery 封裝的 ajax方法里面的 jsonp 請(qǐng)求,說(shuō)來(lái)說(shuō)去,自己都好像忘記了普通的 ajax請(qǐng)求

js原生 ajax 請(qǐng)求
        //1.創(chuàng)建對(duì)象
        var ajax = "";

        if(window.XMLHttpRequest){
            ajax = new XMLHttpRequest();    /* 現(xiàn)代瀏覽器 */
        }else if(window.ActiveXObject){
            ajax = new ActiveXObject("Microsoft.XMLHTTP");  /* 萬(wàn)惡的ie瀏覽器 */
        }

        //2.創(chuàng)建請(qǐng)求

        //get請(qǐng)求方法(拼接url參數(shù))
//      var url="login.php?name="+name+"&password="+pass;
//      ajax.open("GET",url,true);

        //post請(qǐng)求
        ajax.open("POST","login.php",true);
        ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
        var data="name="+name+"&password="+pass;

        //3.發(fā)送請(qǐng)求
//      ajax.send();        //get 方式發(fā)送請(qǐng)求
        ajax.send(data);    //post 方式發(fā)送請(qǐng)求

        //4.捕獲請(qǐng)求狀態(tài)、onreadystatechange表示當(dāng)前請(qǐng)求狀態(tài)

        ajax.onreadystatechange=function(){
            //5.判斷請(qǐng)求狀態(tài)
            if(ajax.readyState==4){
                //6.判斷請(qǐng)求結(jié)果
                if(ajax.status==200){
                    //請(qǐng)求成功將結(jié)果 responseText 放入回調(diào)函數(shù)中
                    succ(ajax.responseText);
                }
            }
        }

注意

通過(guò)檢測(cè)window對(duì)象是否有XMLHttpRequest屬性來(lái)確定瀏覽器是否支持標(biāo)準(zhǔn)的XMLHttpRequest。
注意,不要根據(jù)瀏覽器的navigator.userAgent來(lái)檢測(cè)瀏覽器是否支持某個(gè)JavaScript特性,一是因?yàn)檫@個(gè)字符串本身可以偽造,二是通過(guò)IE版本判斷JavaScript特性將非常復(fù)雜。

當(dāng)創(chuàng)建了XMLHttpRequest對(duì)象后,要先設(shè)置onreadystatechange的回調(diào)函數(shù)。在回調(diào)函數(shù)中,通常我們只需通過(guò)readyState === 4判斷請(qǐng)求是否完成,
如果已完成,再根據(jù)status === 200判斷是否是一個(gè)成功的響應(yīng)。

XMLHttpRequest對(duì)象的open()方法有3個(gè)參數(shù),
第一個(gè)參數(shù)指定是GET還是POST,
第二個(gè)參數(shù)指定URL地址,
第三個(gè)參數(shù)指定是否使用異步,默認(rèn)是true,所以不用寫。

注意,千萬(wàn)不要把第三個(gè)參數(shù)指定為false,否則瀏覽器將停止響應(yīng),直到AJAX請(qǐng)求完成。
如果這個(gè)請(qǐng)求耗時(shí)10秒,那么10秒內(nèi)你會(huì)發(fā)現(xiàn)瀏覽器處于“假死”狀態(tài)。

最后調(diào)用send()方法才真正發(fā)送請(qǐng)求。
GET請(qǐng)求不需要參數(shù),
POST請(qǐng)求需要把body部分以字符串或者FormData對(duì)象傳進(jìn)去。

jquery實(shí)現(xiàn)普通ajax

后臺(tái) php 代碼

當(dāng)然實(shí)現(xiàn)跨域的方法還有很多,html5規(guī)范 的 CORS(全稱Cross-Origin Resource Sharing),是HTML5規(guī)范定義的如何跨域訪問(wèn)資源。

了解CORS前,我們先搞明白概念:
Origin表示本域,也就是瀏覽器當(dāng)前頁(yè)面的域。當(dāng)JavaScript向外域(如sina.com)
發(fā)起請(qǐng)求后,瀏覽器收到響應(yīng)后,首先檢查Access-Control-Allow-Origin是否包含本域,
如果是,則此次跨域請(qǐng)求成功,如果不是,則請(qǐng)求失敗,JavaScript將無(wú)法獲取到響應(yīng)的任何數(shù)據(jù)。

假設(shè)本域是my.com,外域是sina.com,只要響應(yīng)頭Access-Control-Allow-Origin為http://my.com,或者是*,本次請(qǐng)求就可以成功。

可見(jiàn),跨域能否成功,取決于對(duì)方服務(wù)器是否愿意給你設(shè)置一個(gè)正確的Access-Control-Allow-Origin,決定權(quán)始終在對(duì)方手中。
總結(jié)

1、ajax和jsonp這兩種技術(shù)在調(diào)用方式上“看起來(lái)”很像,目的也一樣,都是請(qǐng)求一個(gè)url,然后把服務(wù)器返回的數(shù)據(jù)進(jìn)行處理,因此jquery和ext等框架都把jsonp作為ajax的一種形式進(jìn)行了封裝;

2、ajax和jsonp其實(shí)本質(zhì)上是不同的東西。ajax的核心是通過(guò)XMLHttpRequest獲取非本頁(yè)內(nèi)容,而jsonp的核心則是通過(guò)HTTP來(lái)動(dòng)態(tài)添加

閱讀需要支付1元查看
<