1. 程式人生 > >同源、跨域、jsonp(面試常問)

同源、跨域、jsonp(面試常問)

          提到跨域,就不得不說一下同源策略,同源策略是瀏覽器的一種安全策略,也就說a網站不能隨便讀取b網站的內容,試想一下,如果網站之間都可以隨便讀取互相的檔案,比如一個黑客程式,他利用IFrame把真正的銀行登入頁面嵌到他的頁面上,當你使用真實的使用者名稱,密碼登入時,他的頁面就可以通過Javascript讀取到你的表單中input中的內容,這樣使用者名稱,密碼就輕鬆到手了。

    所謂"同源"是指協議、埠號、域名相同,那麼"跨域"就可以理解為不同源的網站之間的訪問,最常見的應用是當我們呼叫ajax介面時如果不設定跨域瀏覽器會報錯,這證明使用xmlHttpRequest物件不能傳送跨域請求。

   有疑惑的小夥伴肯定會問,那我用a標籤和script標籤請求其他網站,是不是就是跨域了呢?

   這裡要明白跨域是指在當前域下呼叫其他域下的東西,而連結則是直接跳轉到對方的域下了,跟你之前的域名毫無關係。

   如果想從你的網站跨域去另一個網站拿到一些資源,有一個前提條件是另一個網站的伺服器支援跨域,這個需要在服務端設定,不同服務端設定方法不一樣,這裡我們不多說,就看客戶端跨域如何解決。

解決跨域最常見方法是jsonp方式,jsonp是jquery給我們封裝的一個方法,使用方法如下:

$.ajax({
                   url:"http://api.map.baidu.com/telematics/v3/weather?ak=6tYzTvGZSYB5Oc2YGGOKt8&location=天津&output=json",
                   type:"get",
                   dataType:"jsonp",
                   success:function(data){
                       console.log(data);
                   }
               })

   上面程式碼是當我們呼叫外部的一個介面時,通過設定jquery的ajax方法裡面的datatype屬性的值為jsonp就可以成功呼叫這個介面了。

   現在當有人問起你如何解決跨域,你說用jsonp,這時候我相信不懂的人一定還是不懂,哈哈,人家會想jsonp是個什麼鬼?

   這就告訴我們學東西要知其然而知其所以然,也許我們以為script標籤只能引用本地檔案,卻不知script標籤也可以傳送請求,下面就是jsonp的原理

<body>
<input type="button" value="script 標籤傳送請求,接收資料">
<script>
        function getInfo(obj){
             console.log(obj.username);//拿到資料 張三.
        };         document.querySelector("input").onclick=function(){                var script=document.createElement("script");                //能發跨域請求,絕對能發不跨域的請求的                script.src="05cross.php?callback=getInfo";//js 去解析,呼叫這個函式,就會在script 標籤裡面找這個函式。                document.body.appendChild(script);               /*通過js 去接收到資料.*/               //現在的資料直接瀏覽器拿到之後按照js 的方式去解析,所以報錯         } </script> </body>
<?php
        //獲取到的這個叫做getInfo
        $_call=$_GET["callback"];
        $data='{"username":"張三"}';
        echo $_call."(".$data.")";
        //返回到客戶端就是getInfo({"username":"張三"})的呼叫結果
?>
jsonp跨域的原理
       1:使用script 標籤傳送請求,這個標籤支援跨域訪問
       2:在script 標籤裡面給伺服器端傳遞一個 callback
       3:callback 的值對應到頁面一定要定義一個全域性函式(為什麼是全域性?因為服務端接收到callback函式後會返回頁面中的script中去找,如果不寫在全域性作用域中根本找不到)
       4:服務端返回的是一個函式的呼叫。呼叫的時候會吧資料作為引數包在這個函式裡面。

缺點:jsonp只能解決get方式的跨域

那如果要解決post方式的請求如何做呢?答案在這裡:http://write.blog.csdn.net/mdeditor#!postId=60780480