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
舉個栗子:
如: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方式進行請求,所以在請求引數過多的情況下就無法使用了。
以上。