为什么会有JSONP呢,什么又是JSONP呢?
JSONP是用来解决跨域问题的,以前它是跨域问题的克星,由于CORS的出现,它就慢慢的淡出了历史的舞台了,但为什么还要说它呢,主要就是面试官喜欢问啊(无奈)。
什么是跨域问题?
想要了解这个问题,那么必须要清楚 同源 和 不同源 的定义。
同源定义:两个url的地址的 协议 与 主机 与 端口 一致
不同源定义:两个url地址的 协议 主机 端口任何一个不一致
如果对于里面的相关概念不懂的朋友,用一个网站给你说明白
就拿百度网站来说的:https://www.baidu.com:443
协议: https, 主机:www.baidu.com(域名), 端口:443
不输入端口也会默认是443,因为hhtps协议的默认端口号就是443
跨域问题其实就是:浏览器使用ajax时,如果请求的 接口地址 和当前 打开页面 地址不同源就叫跨域。
跨域问题的前提是浏览器通过ajax对服务器发送请求。那么为了解决跨域问题呢,那么久绕开ajax来发送请求,就有人使用script标签的src属性来发送请求,这样就可以解决跨域的问题了。
这个也是JSONP的原理所在
现在就来写代码展示一下吧。
这个是前端使用ajax发送请求
这个是后端接口页面,使用node.js写的。
在这里先给大家运行看看是什么情况
大家看第一个错误就行了,第二个错误是因为我没有开启服务器而报的。第一个错误就是跨域问题。其中报错中显示了这么一段“Access-Control-llow-Origin”,这是响应头。简单来说就是不允许你访问我,就像你去别人家被狗咬一样,把狗看成是这个错误。
CORS响应头 -Access-Control-Allow-Origin
响应头部中跨域携带一个Access-Control-Allow-Origin字段
其中origin参数指定了允许访问该资源的外域URL
下面的栗子的字段值将只允许来自http://lhj.cn的请求:
栗子:res.setHeader("Access-Control-Allow-Origin", "http://lhj.cn");
下面的栗子的字段值将允许来自任何域的请求:
栗子:res.setHeader("Access-Control-Allow-Origin", "*");
这就是所谓跨域问题,解决这个跨域问题其实简单,下面这行就可以搞定
res.setHeader("Access-Control-Allow-Origin", "*");
这行代码是所有意思呢,就是允许任何域来访问。
node.js中添加
得到的结果:
这时就解决了跨域问题了
但是这不是我们所要讲的,上面解决跨域问题其实不是使用JSONP来解决的,而是使用CORS来解决的。
这时我们就真正使用JSONP来解决问题。根据JSONP 原理,不再使用ajax案例发送请求,而是使用script标签的src属性来发送请求。
直接运行的结果为:
如果细心的朋友会发现在最下面还是有一个错误。其实这不算是错误吧。带大家来分析为什么会有这样的错误出现。
要讲明这个那么就必须来看看刚刚用node.js写的后端代码。
如果大家能了解红色方框的内容,那么久明白了。res.send是响应刚刚请求从前端发送过来的请求体。 模板字符串中的${req.query.callback},req.query是获取到前端的请求体数据。大家看到请求网站后面的?callback=fn没有,这个就是req.query,而req.query.callback = fn;
有些有些同学就会说为什么不把${req.query.callback}直接写成fn呢,是可以,但是这样写就写死了,如果另外一个前端的同学定义的函数为add呢。
红色方框返回到前端的内容为fn({anme: "黄家驹", age: 31})的js代码
纵观前端刚刚写的代码中,并没有找到哪里有定义fn函数。所以就会报错误,如果定义了就不会报错了,还会将其执行。来试试看吧。
得到的结果为:
这时就不会报错了,还会将定义的fn函数给执行。
希望可以帮到你