JSONP跨域访问,通过动态加入javascript实现
1. 什么是JSONP?
JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
2.为什么使用JSONP?
由于 JSON 只是一种含有简单括号结构的纯文本,因此许多通道都可以交换 JSON
消息。因为同源策略的限制,我们不能在与外部服务器进行通信的时候使用
XMLHttpRequest。而JSONP是一种可以绕过同源策略的方法,即通过使用 JSON 与 < script>
标记相结合的方法,从服务端直接返回可执行的JavaScript函数调用或者JavaScript对象。
JSONP的安全问题:我们可以使用若干种方法在 JavaScript 程序中动态地生成代码。最著名的函数之一就是 eval()
函数,该函数允许您将任意字符串做为 JavaScript 代码执行。然而,肆无忌惮地使用该函数是非常危险的。遗憾的是,一些使用广泛的
JavaScript 库在内部直接使用 eval() 函数。由于 JSON 是以 JavaScript
的一个子集为基础的,所以脚本内容会潜在地包含恶意代码。然而,JSON 是JavaScript 的一个安全的子集,不含有赋值和调用。因此,许多
JavaScript 库使用 eval() 函数将 JSON 转换成 JavaScript 对象。要利用这点,攻击者可以向这些库发送畸形的
JSON 对象,这样 eval() 函数就会执行这些恶意代码。可以采取一些方法来保护 JSON 的使用。这里提供一种方法:使用RFC 4627 中所定义的正则表达式确保 JSON 数据中不包含活动的部分。
下面演示了如何使用正则表达式检查 JSON 字符串:
- var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
- text.replace(/"(\\.|[^"\\])*"/g, ''))) &&
- eval('(' + text + ')');
其实 jsonp 是个很简单的一个东西。主要是利用了 <script/>标签对javascript文档的动态解析来实现。(其实也可以用eval函数)
- < script type=" text/javascript" >
- function jsonpCallback(result)
- {
- alert(result.msg);
- }
- < /script>
- < script type=" text/javascript" src=" http://crossdomain.com/jsonServerResponse?jsonp=jsonpCallback" > < /script>
其中 jsonCallback 是客户端注册的,获取跨域服务器上的json数据后,回调的函数。
http://crossdomain.com/jsonServerResponse?jsonp=jsonpCallback
这个 url 是跨域服务器取 json 数据的接口,参数为回调函数的名字,返回的格式为:
- jsonpCallback({ msg:'this is json data'} )
Jsonp原理:
首先在客户端注册一个callback, 然后把callback的名字传给服务器。此时,服务器先生成 json 数据。然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.
最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并执行返回的javascript文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)
var b = document.createElement("script");
b.src = "https://account.xxxxxx.com/pass/userInfoJsonP?userId=" + this.miid + "&callback=Xmeb.App.loginNavigation.getAccountInfo";
b.type = "text/javascript";
b.async = true;
document.getElementsByTagName("head")[0].appendChild(b);