说明
关于跨域问题的解决方案多达七、八种,你不要说哪有这么多,我不跟你较真哈,你也别跟我较真哈,?!自行百度
或JSONP
,你要非说JSONP
用的不是最多的,我不信哦,你信好了,哈哈,你开心就好?
关于跨域
- 浏览器的同源策略
要了解什么是
跨域
你需要了解什么是浏览器的
同源策略
- 浏览器允许访问的资源必要条件
其实说白了就一句话
相同域名、相同协议、相同端口
浏览器才允许访问,这是出于安全方面的考虑,其它一律不允许访问!
- 浏览器允许访问的同源资源俗解
比如说:a.com/article/mid/512
要访问a.com/data/detail/512
是允许访问的,a.com/article/mid/512
要访问b.com/data/detail/512
是拒绝的!
- A域名下访问B域名资源
那么非要访问不同域名下的资源,怎么办呢?那么问题来了!跨域
不使用跨域访问
这种方式是在没有跨域访问其它域名资源URL常规做法!而访问其它域名资源URL是不可行的!
前端代码
<!DOCTYPE html> <html lang="en"> <head> <Meta charset="UTF-8"> <title>JSONP TEST</title> <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> </head> <body> <script> $.ajax({ type : 'GET',dataType : 'JSON',url : "http://warnerwu.centos.dev/?c=adCreativeLib&a=api&type=list",success : function (data){ console.log(data); } }); </script> </body> </html>
浏览器开发者工具控制台提示
可以发现控制台并没有输出任何返回数据,因为它也没有数据可输出,而是给出了下面这样一个提示信息:
浏览器开发者工具网络请求列表详情
而在网络请求列表可以看到请求资源URL没有返回任何数据
后端返回数据形式
既然通过jQuery
的AJAX
方法返回数据形式是JSON
格式,请求资源URL,没有获取到任何数据,通过浏览器直接访问资源URL可以正常获取到数据!
使用JSONP跨域访问资源
前端或客户端处理
从上面可以看到通过浏览器直接访问资源URL也就是API接口是可以获取到数据的,而通过返回数据形式为JSON
的方式是拒绝访问的,那么要想通过在tem.mac.dev
这个域名访问warnerwu.centos.dev
域名下的API接口URL资源就需要使用JSONP
,只需要将jQuery
中AJAX
方法中的dataType
值修改为即可
dataType : 'JSONP'
注意
这里也只是限于把上面所说的「直接通过浏览器访问资源API接口URL获取到的数据」通过JSONP的形式给获取到了而已也只是仅仅如此,下面再次刷新页面通过
JSONP
访问资源API接口URL来验证这一点!
浏览器开发者工具控制台提示
在控制台下已经看不到已拦截跨域请求
的警告信息啦!而是空空如也
哦 ?
浏览器开发者工具网络请求列表详情
那既然在控制台
看不到任何警告
信息也看不到数据输出,不防看一下网络
请求列表是怎么样的!
从
网络
请求列表中的最后一条可以看出这个访问资源API接口的完整URL是:
http://warnerwu.centos.dev/?c=adCreativeLib&a=api&type=list&callback=jQuery21408945840059161158_1519958486174&_=1519958486175
这里你就会发现这个请求资源地址与AJAX
方法中的url
参数值截然不同! 它多了两个参数:
callback=jQuery21408945840059161158_1519958486174&_=1519958486175
是这样的,在使用jQuery
的AJAX
方法时,如果指定返回数据方式是JSONP
时,也就是AJAX
参数对象字面量dataType : 'JSONP'
时,如下所示:
$.ajax({ type : 'GET',dataType : 'JSONP',success : function (data){ console.log(data); } });
它就会在发起请求资源时在AJAX
方法参数对象字面量url
的具体链接上自动添加参数callback
和_
,而且这两个参数的值基本上永远不会重复
AJAX参数对象字面量 url
JSONP参数值
- callback: 值为随机以
jQuery
开头后跟随机数字字符串的回调函数名称 - _: 值为随机数字字符串,它保证每次发起
AJAX
请求都是新的,而不会使用浏览器已请求过的URL缓存机制
已存在资源
在上图中可以看到网络
请求资源列表中API接口访问URL的具体参数列表,而响应
具体是这样的:
可以看到响应
返回的是JSON格式的数据,这样是不对的!不防再看一下控制台
:
可以看到控制台依然是空空如也
!什么都没有,到目录为止其实前端或客户端
所做的工作已经完成!接下来就是服务器端
API接口要做些修改操作喽!
服务器端处理
这里使用的服务器端语言是 PHP
,其它语言也是一样处理哦!
其实服务器端所以要的调整很简单,只需要获取请求参数callback
,然后返回以callback
参数值为函数名称的JSONP格式的编码数据字符串即可
API接口调整之前
这种处理方式是针对不存在跨域API接口请求获取数据时通常的做法,如果是JSONP跨域请求API接口获取数据时就不通用喽!
API接口调整之后
可以看到这里在服务器端处理为通用请求获取数据返回形式,不管是否是跨域请求API接口均可使用!
再次刷新页面跨域请求API接口数据
你会发现请求API接口数据成功,并且请求时的callback
参数值和返回的JSONP格式数据方法名称一致,获取到的JSONP格式数据怎么处理的呢?当请求成功时就会执行以
jQuery
下AJAX
方法生成的callback
参数值对就的函数,恰好这个正是从服务器端返回的JSONP格式数据,函数执行结束后返回主题数据也就是与服务器端编码返回之前的数据类型一致的数据形式
以上是跨域请求API接口通过控制台输出的数组数据
以上是通过浏览器直接访问API接口获取的数组数据
总结
说白了使用JQuery
的AJAX
方法实现跨域请求资源是非常简单的!
前端代码
$.ajax({ type : 'GET',success : function (data){ console.log(data); } });
服务器端代码
其实非常简单的问题在这里说了这么多,大家见谅!?以上就是
JSONP跨域访问API接口深入理解
的详细过程,谢谢您的支持!希望本文对你的工作和学习有所帮助
如果觉得还不错并且也长知识了,怎么感谢我呢? 妈呀! 点赞啊!
Good Luck! from warnerwu at 2018.03.02 PM,email address is warnerwu@126.com