1. 程式人生 > >JSONP跨域原理及示例

JSONP跨域原理及示例

同源策略下,伺服器不能請求該伺服器以外的資源,及不能跨域請求。何為跨域,簡單說就是協議+主機名+埠號(存在的話)三者之一不同就可稱之為跨域。如:

1.http: //www.test.com 和 https: //www.test.com 之間協議不同,存在跨域
2.blog.csdn.net 和 blog.csdn.net:8080 之間埠號不同
3.write.csdn.net 和 blog.csdn.net 之間主機名不同

但是,如果需要進行跨域請求資源時怎麼辦呢?目前常用的方法有JSONP和CROS兩種方法(本篇博文主要寫一些JSONP相關的東西)。JSONP的原理是什麼呢?html標籤中存在一些如img、script等標籤球可以通過src屬性進行資源的請求。JSONP就是通過script

標籤來進行跨域資源的請求的。當發起JSONP請求的時候,伺服器就會返回一段js指令碼,請求方通過返回的該段指令碼就可以獲得請求的資源了。

舉個栗子:
如:http://localhost:8080/webcontent/test.html頁面存在
一個 http ://localhost:8888/jsonp/test?callback=Test 的請求,那麼伺服器就會返回Test({“test”:”this is json”})的字串,該字串可看做是一個名為Test的function,其引數為一個json object。當呼叫方得到該字串時就會自動執行Test方法,來進行後續的處理。

程式碼如下:

呼叫方的JS程式碼

<script>
    function Test(i) {// 該方法會在結果返回時被自動呼叫
        console.log(i.test);
        console.log(JSON.stringify(i));
    }
</script>
<script src="http://127.0.0.1:8888/SpringmvcDemo/jsonp/msg?callBack=Test"></script>

伺服器端程式碼:

@Controller
@RequestMapping("/jsonp")
public class JsonpTestController
{
@ResponseBody @RequestMapping("/msg") public String responseJsonp(HttpServletRequest request, @RequestParam String callBack) { String testJson = "{\"test\":\"this is json\"}"; String jsonp = callBack + "(" + testJson + ");"; return jsonp; } }

若直接請求伺服器,會返回如下結果

這裡寫圖片描述

JSONP跨域請求返回的結果(開發者工具控制檯)

這裡寫圖片描述

通過以上演示可以看出,jsonp其實就是json外面包裹一個回撥函式,通過該回掉函式就可以對json資訊進行後續的處理解析。

在實際專案中通常使用JQUERY進行JSONP呼叫
示例程式碼:

$.ajax({
        async:false,
        type:'get',
        url: 'http://127.0.0.1:8888/SpringmvcDemo/jsonp/msg',
        cache : false,
        dataType: "jsonp",
        success: function(data) {
            // 進行相應處理
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(errorThrown);
        }
    });

這裡寫圖片描述

JQUERY會在請求的Url後面加上callback=動態生成的回撥函式名,伺服器返回的資料就是生成的動態回撥函式包裹json。JQUERY會預設使用callback,當然也可以指定callback為其他值,也可以指定回撥函式名。

JSONP很方便的解決了跨域問題,但是由於本身只能採用get方式進行請求,所以在請求引數過多的情況下就無法使用了。

以上。