天天看點

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跨域請求傳回的結果(開發者工具控制台)

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);
        }
    });
           
JSONP跨域原理及示例

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

JSONP很友善的解決了跨域問題,但是由于本身隻能采用get方式進行請求,是以在請求參數過多的情況下就無法使用了。

繼續閱讀