概念:
什么叫跨域?
同源策略:它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。
所谓同源是指,域名,协议,端口相同。
同源的脚本才会被执行。
例如在www.aaa.com/index.aspx里希望获得www.bbb.com/Map.ashx返回的数据,正常的ajax无法获取。
跨域即绕过同源策略取得数据。
但是凡事都有特例,想想我们常写的
<img src="http://www.baidu.com/img/bd_logo1.png" />
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.min.js"></script>
可以很轻松获取到所需的东西,这不就是跨域的一种方式吗?
而jsonp重点就是借助script标签来完成跨域了。
原理:
1、www.aaa.com/index.aspx下的head里写:
<script type='text/javascript'> function Show(name){ alert("I'm " + name); } </script> <script type='text/javascript' src="www.bbb.com/test.js"></script>
2、www.bbb.com/test.js里面写:
Show("jerry");
这样运行www.aaa.com/index.aspx时,会弹出"I'm jerry"没什么疑问。
正是运用这个原理,我们可以做更多的事情,获取跨域数据,执行回调函数。
例1:
在第一个页面head中写如下几句:
<script type="text/javascript"> function myFn(jsonObj){ alert("welcome, " + jsonObj.name); } </script> <script type="text/javascript" src="www.bbb.com/Map.ashx?callback=myFn"></script>
在www.bbb.com/Map.ashx中写下:
string callback=context.Request.QueryString["callback"]; string json="{'name':'jerry'}"; //服务端处理后要传回的数据 context.Response.Write(callback + "(" + json + ")"); //结果为myFn({'name':'jerry'})
其实很好理解,首先定义了函数myFn,然后跨域的script标签通过QueryString传了一个叫做callback的参数,值为myFn。
这时服务端获取到其callback参数的值,并通过字符串拼接的方式输出 myFn({'name':'jerry'})
这句话直接在第一个页面中运行了。这样不仅跨域得到了数据,还在获得数据之后执行了回调函数。
值得注意的是第一个页面中地址栏传值的参数名要和服务端获取的参数名相同。
例2、jquery中的$.ajax跨域
jquery是如此的方便以至于我用过之后便对它爱不释手。
例1中的服务端不变,在客户端调用时变为:
function myFn(jsonObj){ alert("welcome, " + jsonObj.name); }
$.ajax({ url:"www.bbb.com/test.ashx", dataType:"jsonp", jsonp:"callback", //参数名 jsonpCallback:"myFn", //参数值,即回调函数名 success:function(data){ //成功了会自动弄个执行返回的js,即服务端拼接出的myFn({'name':'jerry'});
//而后再执行此处代码
}
});
例3、当只需要数据,不需要执行函数时
服务端:
string json="{'name':'jerry'}"; //服务端处理后要传回的数据 context.Response.Write(json);
客户端:
$.ajax({ url:"www.bbb.com/test.ashx", dataType:"jsonp", success:function(data){ //会报错,无法只返回数据。必须返回方法名+数据才可以 } });
例3会报错!
在日常工作中很有用处,如有理解不到位还望指正!