1

说明

关于跨域问题的解决方案多达七、八种,你不要说哪有这么多,我不跟你较真哈,你也别跟我较真哈, ?!自行 百度Google, 这里不会跟你说那么多种, 只说使用最多的一种 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没有返回任何数据

浏览器网络请求列表详情

后端返回数据形式

既然通过 jQueryAJAX 方法返回数据形式是 JSON 格式, 请求资源URL, 没有获取到任何数据, 通过浏览器直接访问资源URL可以正常获取到数据!

后端返回数据形式

使用JSONP跨域访问资源

前端或客户端处理

从上面可以看到通过浏览器直接访问资源URL也就是API接口是可以获取到数据的, 而通过返回数据形式为 JSON 的方式是拒绝访问的, 那么要想通过在 tem.mac.dev 这个域名访问 warnerwu.centos.dev 域名下的API接口URL资源就需要使用 JSONP, 只需要将 jQueryAJAX 方法中的 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
是这样的, 在使用 jQueryAJAX 方法时, 如果指定返回数据方式是 JSONP 时, 也就是 AJAX 参数对象字面量 dataType : 'JSONP' 时, 如下所示:
$.ajax({
    type : 'GET',
    dataType : 'JSONP',
    url : "http://warnerwu.centos.dev/?c=adCreativeLib&a=api&type=list",
    success : function (data){
        console.log(data);
    }
});
它就会在发起请求资源时在 AJAX 方法参数对象字面量 url 的具体链接上自动添加参数 callback_, 而且这两个参数的值基本上永远不会重复

AJAX参数对象字面量 url JSONP参数值
  • callback: 值为随机以 jQuery 开头后跟随机数字字符串的回调函数名称
  • _: 值为随机数字字符串, 它保证每次发起 AJAX 请求都是新的, 而不会使用浏览器已请求过的URL 缓存机制 已存在资源

AJAX参数对象字面量JSONP参数值

在上图中可以看到 网络 请求资源列表中API接口访问URL的具体参数列表, 而 响应 具体是这样的:

AJAX返回值类型为JSONP

可以看到 响应 返回的是JSON格式的数据, 这样是不对的!不防再看一下 控制台

控制台具体内容

可以看到控制台依然是 空空如也!什么都没有, 到目录为止其实 前端或客户端 所做的工作已经完成!接下来就是 服务器端 API接口要做些修改操作喽!

服务器端处理

这里使用的服务器端语言是 PHP, 其它语言也是一样处理哦!

其实服务器端所以要的调整很简单, 只需要获取请求参数 callback, 然后返回以 callback 参数值为函数名称的JSONP格式的编码数据字符串即可
API接口调整之前
这种处理方式是针对不存在跨域API接口请求获取数据时通常的做法, 如果是JSONP跨域请求API接口获取数据时就不通用喽!

API接口调整之前

API接口调整之后

API接口调整之后

可以看到这里在服务器端处理为通用请求获取数据返回形式, 不管是否是跨域请求API接口均可使用!
再次刷新页面跨域请求API接口数据

再次刷新页面跨域请求API接口数据

你会发现请求API接口数据成功, 并且请求时的 callback 参数值和返回的JSONP格式数据方法名称一致, 获取到的JSONP格式数据怎么处理的呢?

当请求成功时就会执行以 jQueryAJAX 方法生成的 callback 参数值对就的函数, 恰好这个正是从服务器端返回的JSONP格式数据, 函数执行结束后返回主题数据也就是与服务器端编码返回之前的数据类型一致的数据形式

以上是跨域请求API接口通过控制台输出的数组数据

以上是跨域请求API接口通过控制台输出的数组数据

以上是通过浏览器直接访问API接口获取的数组数据

以上是通过浏览器直接访问API接口获取的数组数据

总结

说白了使用 JQueryAJAX 方法实现跨域请求资源是非常简单的!

前端代码

$.ajax({
    type : 'GET',
    dataType : 'JSONP',
    url : "http://warnerwu.centos.dev/?c=adCreativeLib&a=api&type=list",
    success : function (data){
        console.log(data);
    }
});

服务器端代码

服务器端代码

其实非常简单的问题在这里说了这么多, 大家见谅!?

以上就是 JSONP跨域访问API接口深入理解 的详细过程, 谢谢您的支持!

希望本文对你的工作和学习有所帮助

如果觉得还不错并且也长知识了, 怎么感谢我呢? 妈呀! 点赞啊!

Good Luck! from warnerwu at 2018.03.02 PM, email address is warnerwu@126.com


wumoxi
431 声望40 粉丝

如果不曾让我见过阳光,至少我还可以忍受黑暗