工作中我们经常会请求其他域下的资源(因为同源策略),这个时候就遇到了跨域(协议,端口,域名任何一个不同就算是跨域)。解决跨域的一种常用办法就是jsonp,虽然他有局限性(只支持get请求),不过优点是兼容老式浏览器(不过现在好像很少有人在意老式浏览器了)。jsonp的基本原理:就是通过动态创建script标签,script标签的src是没有跨域限制的(可以请求txt、php)。
原生javascript使用jsonp:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{
margin: 0;
padding: 0;
}
input{ width:300px; height:30px; border:1px solid lightgray; margin-top: 150px; margin-left: 200px; padding-left: 5px; }
ul{ width:307px; list-style: none; margin-left: 200px; display: none; } li{ height:30px; border: 1px solid lightgray; line-height: 30px; padding-left: 5px; }
</style>
<script>
function callbackD(response){
var oUl = document.getElementById('ulList');
var html='';
if(response.s.length !=0){
oUl.style.display='block';
for(var i = 0;i<response.s.length;i++){
html+='<li>'+response.s[i]+'</li>'
}
}
oUl.innerHTML = html;
}
window.onload = function(){
var oData = document.getElementById('inputSearch');
var oUl = document.getElementById('ulList');
oData.onkeyup = function(){
if(oData.value != ''){
var script = document.createElement("script");
script.src='http://unionsug.baidu.com/su?wd='+this.value+'&p=3&cb=callbackD';
//添加给body的(成为body包涵的孩子)
document.body.appendChild(script);
}else{
oUl.style.display='none';
}
}
};
</script>
</head>
<body>
<input type="text" id="inputSearch">
<ul id="ulList">
</ul>
</body>
</html>
效果图:
jquery使用jsonp跨域请求
<html>
<head>
<title>跨域测试</title>
<script src="js/jquery-1.7.2.js"></script>
<script>
function showData (data) {
//console.info("调用showData");
var result = JSON.stringify(data);
$("#text").val(result);
}
$(document).ready(function () {
$("#btn").click(function () {
$.ajax({
url: "json请求地址",
type: "GET",
dataType: "jsonp", //指定服务器返回的数据类型
jsonp: "theFunction", //指定参数名称
jsonpCallback: "showData", //指定回调函数名称(绿色部分可省略,默认毁掉函数是success)
success: function (data) {
//console.info("调用success");
}
});
});
});
</script>
</head>
<body>
<input id="btn" type="button" value="跨域获取数据" />
<textarea id="text" style="width: 400px; height: 100px;"></textarea>
</body>
</html>
说明:
看上图,指定特定的回调函数(红色部分),回调函数你可以写到<script>下(默认属于window对象),或者指明写到window对象里,看jquery源码,可以看到jsonp调用回调函数时,是调用的window.theFunction(jsonp: "theFunction"可不写,默认是callback)。然后看调用结果,发现,请求时带的参数是:callback=showData;调用回调函数的时候,先调用了指定的showData,然后再调用了success。所以,success是返回成功后必定会调用的函数,就看你怎么写了。
总结:jQuery ajax方式以jsonp类型发起跨域请求,其原理跟<script>脚本请求一样,因此使用jsonp时也只能使用GET方式发起跨域请求。跨域请求需要服务端配合,设置callback,才能完成跨域请求。