从事前端开发的小伙伴肯定都用过jquery的ajax请求,但如果需要跨域请求,就需要用到jsonp,因为默认的ajax跨域请求会被浏览器拦截,拦截原因是因为支持JAVAscript的浏览器都会使用同源策略这个安全策略。
同源策略看百度解释:
同源策略,它是由Netscape提出的一个著名的安全策略。 现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。 当一个浏览器的两个tab页中分别打开百度和谷歌的页面 当一个百度浏览器执行一个脚本的时候会检查这个脚本是属于哪个页面的 即检查是否同源,只有和百度同源的脚本才会被执行。
ajax
下面说一个使用场景:
网站域名是:http://www.a.com
服务器后端地址:http://www.b.com/api/,后端文件内容如下
var callBackName = Request.QueryString["callback"]; string jsonData = "{"message":"ok"}"; return callBackName+"("+ jsonData+ ")";
由于域名不一样,前端请求后端数据就需要用到跨域请求,jquery跨域请求的代码如下:
$.ajax({ url: "http://www.b.com/api/", type: "GET", dataType: "jsonp", //必须指定为jsonp jsonp: "callback",//服务端用于接收callback调用的function名的参数 success: function (data) { console.log(data); } });
这段代码执行后会在浏览器的控制台输出:{"message":"ok"}
上面这种写法是jquery给我们封装好的,平时工作中很多朋友都会用,但是很多人不知道原理是什么,实际上这个请求的原理用javascript的原生写法就是:
<script src="http://www.b.com/api/"></script>
通过script的开放策略,可以调用任何地址,知道原理后,我们用原生的javascript来封装一个自己的jsonp方法。
设计步骤如下:
1、定义一个jsonp函数,用于处理接收到的跨域数据。
2、函数中生成一个dom节点(script节点),然后src属性上面记入发送的目的URL以及参数。
3、声明一个全局函数,用来执行回调。
直接上代码,下面是我为这次教程特意封装好的演示代码。
<script type="text/javascript"> //obj参数是一个对象 function jsonp(obj) { var script = document.createElement("script"); var callBackFn = obj.callback; //组合请求URL script.src = obj.url + "?callback=" + callBackFn; //获取数据 for (key in obj.data) { script.src += "&" + key + "=" + obj.data[key]; } //将创建的新节点添加到BOM树上 document.getElementsByTagName("body")[0].AppendChild(script); //定义一个回调函数名称同名的全局方法、 window[callBackFn] = function (object) { obj.success(object); delete window[callBackFn]; //移除回调函数 script.parentNode.removeChild(script);//执行完毕后移除节点 } } //调用jsonp,跨域请求http://www.b.com/api/ jsonp({ url: "http://www.b.com/api/", callback: "callback", data: { "id": 1 }, success: function (data) { console.log(data); //输出:{"message":"ok"} } }); </script>
这里只进行核心的封装,载入,出错的处理、参数的空值判断等等自己完善,通过上面的演示代码,小伙伴们应该对jsonp的原理有了更清晰的认识。
如果这篇教程能帮助到各种小伙伴,帮忙转发一下,后续我会继续分享一些javascript开发相关的经验和技巧。