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方式進行請求,所以在請求參數過多的情況下就無法使用了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章