RJ博客

前端实现跨域的三种方法(基于PHP接口)

本文目录

由于在工作中需要使用AJAX请求其他域名下的请求,但是会出现拒绝访问的情况,这是因为基于安全的考虑,AJAX只能访问本地的资源,而不能跨域访问。

比如说你的网站域名是aaa.com,想要通过AJAX请求bbb.com域名中的内容,浏览器就会认为是不安全的,所以拒绝访问。会出现跨域问题的几种情况:

349000064ea1c1e1107.jpg

实现跨域的三种方案:代理、JSONP、XHR2(XMLHttpRequest Level 2)。


第一种方法 代理:这种方式是通过后台(PHP、JAVA等)获取其他域名下的内容,然后再把获得内容返回到前端,这样因为在同一个域名下,所以就不会出现跨域的问题。有点类似爬虫,最常用的就是直接用 file_get_contents 函数获取网页内容,具体可参考:

http://www.oschina.net/code/snippet_861770_19638

详见方法三的代码:跨域+跨域。

即本地跨域访问nearby.wang,再由nearby.wang跨域访问网易云音乐个人主页。

方法一其实就是nearby.wang跨域访问网易云音乐个人主页这个阶段。


第二种方法 JSONP(只支持GET请求):后来人们发现,在调用Js文件的时候不受跨域的影响,这样就衍生了第二种方案。就是在远程服务器端把数据装入js文件中,供客户端调用和进一步处理(就是服务端返回的数据在客户端当js代码去执行,因此对返回数据格式有要求)。详细实现原理可参考:

https://tonghuashuo.github.io/blog/jsonp.html

客户端代码片段如下 test2.html,以下分别为jQuery和原生js写法:

<script type="text/javascript">
    //jQuery写法
    $.ajax({
        url: "http://nearby.wang/ajaxtest.php",
        type: "GET",
        dataType: 'JSONP',
        jsonp: "callback",
        jsonpCallback: "dosomething",
        success: function(result){
            console.log(result);
        }
    });
</script>
<script type="text/javascript">
    //原生js写法
    // 实现回调函数,这里没有了 jQuery 的封装,必须手动指定并实现
    var dosomething = function(data){
        console.log(data);
    };

    // 提供 JSONP 服务的 URL 地址,查询字符串中加入 callback 指定回调函数
    var url = "http://nearby.wang/cloudMusic.php?callback=dosomething";

    // 创建 <script> 标签,设置其 src 属性
    var script = document.createElement('script');
    script.setAttribute('src', url);

    // 把 <script> 标签加入 <body> 尾部,此时调用开始。
    document.getElementsByTagName('body')[0].appendChild(script); 
</script>

服务端代码片段如下 ajaxtest.php:

<?php 
/**
 * 网易云音乐个人信息爬虫
 * Author : RJ
 * Date   : 20170606
 */

header('Access-Control-Allow-Origin:*');
header('Access-Control-Allow-Methods:POST,GET');

include 'ganon.php'; //爬虫html解析文件

$url = "http://music.163.com/user/home?id=59986101";

$html= file_get_dom($url);
$event_count = $html("#event_count")[0]->getPlainText();
$follow_count = $html("#follow_count")[0]->getPlainText();
$fan_count = $html("#fan_count")[0]->getPlainText();

$data=array();
$data['event_count'] = $event_count;
$data['follow_count'] = $follow_count;
$data['fan_count'] = $fan_count;

$result   = json_encode($data);
$callback = isset($_GET['callback']) ? $_GET['callback'] : 'null';
echo $callback."(".$result.")";

运行结果:

blob.png


第三种方法 CORS:XMLHttpRequest Level 2:HTML5提供的XMLHttpRequest Level 2已经实现了跨域访问以及其他的一些新功能,这需要在远程服务器端添加如下代码:

header('Access-Control-Allow-Origin:*'); //*代表可访问的地址,可指定域名
header('Access-Control-Allow-Methods:POST,GET');

这样在客户端使用常规的AJAX代码即可,更详细使用方法可参考:

http://www.cnblogs.com/xiezn/p/5651093.html

客户端代码片段如下 test2.html:

<script type="text/javascript">
    var jsontree;
    $.ajax({
        url: "http://nearby.wang/ajaxtest.php",
        type: "GET",
        success: function(result){
            console.log(result);
        }
    });
</script>

服务端代码片段如下 ajaxtest.php:

<?php 
/**
 * 网易云音乐个人信息爬虫
 * Author : RJ
 * Date   : 20170606
 */

header('Access-Control-Allow-Origin:*'); //*代表可访问的地址,可以设置指定域名
header('Access-Control-Allow-Methods:POST,GET');

$url = "http://music.163.com/user/home?id=59986101";
$html= file_get_contents($url);
die($html);

运行结果:

blob.png


总结:

代理实现最麻烦,但使用最广泛,任何支持AJAX的浏览器都可以使用这种方式。

JSONP相对简单,但只支持GET方式调用。

XHR2最简单,但只支持HTML5,如果你是移动端开发,可以选择使用XHR2。


Refer:

http://blog.csdn.net/ldx891113/article/details/50887776


相关推荐

发表评论