跨域解决方案

跨域解决方案

 

• 前期准备

用WAMP搭建两个站点分别:http://www.example.com 、 http://api.example.com,很显然第一个站点是主站点,第二个站点是提供服务的站点(当然我们在实际的架构上也是这种方式,我们还可以为提供静态资源专门配置一个站点诸如:http://assets.example.com )。

• JSONP解决GET跨域

关于跨域问题出现的,是因为浏览器 同源策略 ,本文就不一一概述了这里主要讲干货,JSON和JSONP其实就像Java和JavaScript的区别,你可以理解为雷锋和雷锋塔的区别,JSONP是我们程序猿想出的跨域的解决方案,跟JSON没有办毛线的关系,我们先举一个通俗易懂的栗子:

首先在 http://api.example.com 域下新建一个文件:get_user_info.php,其内容

12 $user_info = '{ "name": "张三", "age": "18" }';echo "get_user_info($user_info)";

然后在 http://www.example.com 域下创建一个文件:index.html,其内容

123456 <script> function get_user_info(data) { console.log(data); }</script><script src="http://api.example.com/get_user_info.php"></script>

最后我们可以看到控制台输出的结果。其实这就是一个最基础的JSONP跨域,很显然我们利用了script标签发送GET请求,其实jQuery的实现也是采用这种方式,需要注意的是JSONP只支持GET请求。

1234567 $.ajax({ url: 'http://api.example.com/get_user_info.php', dataType: 'jsonp', jsonpCallback: 'get_user_info'}).done(function (data) { console.log(data);});

• 设置Access-Control-Allow-Origin响应头

显然JSONP只支持GET请求,那么对于POST请求它就无能为力了,这个时候我们需要在服务端配置响应头Access-Control-Allow-Origin,并且添加允许跨域的域名

123 header('Access-Control-Allow-Origin: http://www.example.com');$user_info = '{ "name": "张三", "age": "18" }';echo $user_info;

需要注意的是响应头允许跨域的域名结尾不要加‘/’,诸如 header('Access-Control-Allow-Origin: http://www.example.com/'); ,假如需要允许跨多个域名需如下配置

1234567 $origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : ''; $allow_origin = array('http://www.example.com', 'http://www.example2.com');if(in_array($origin, $allow_origin)){ header('Access-Control-Allow-Origin:'.$origin); }

通过设置Access-Control-Allow-Origin响应头实现跨域,GET/POST请求方式都能够实现。

• Apache反向代理

步骤一

配置Apache的httpd.conf文件,取消如下注释

1234 LoadModule proxy_module modules/mod_proxy.soLoadModule proxy_connect_module modules/mod_proxy_connect.soLoadModule proxy_ftp_module modules/mod_proxy_ftp.soLoadModule proxy_http_module modules/mod_proxy_http.so

步骤二

配置httpd-vhosts.conf文件

12345678 <VirtualHost *:80> DocumentRoot "D:/workspace/tech/www.example.com" ServerName www.example.com ##反向代理设置 ProxyPass /action http://api.example.com/action ProxyPassReverse /action http://api.example.com/action</VirtualHost>

步骤三

修改主站index.html文件,注意此时不要添加 http://api.example.com 这个域名前缀,因为我们做了反向代理,当我们访问 http://www.example.com/action/get_user_info.php,其实就是访问http://api.example.com/action/get_user_info.php

1234567 $.ajax({ url: 'action/get_user_info.php', dataType: 'jsonp', jsonpCallback: 'get_user_info'}).done(function (data) { console.log(data);});

总结

本文介绍了三种最基础的跨域解决方案,无非就是JSONP、设置Access-Control-Allow-Origin响应头和反向代理代理这几种方式,个人觉得反向代理方式最简洁省事儿,只需要在服务器端配置即可。而其余两种都需要通过程序方式,相对来说开发成本较大。当然跨域的解决方法还有很多,诸如postMessage、iframe、PHP中curl和flash等等,这里面也有较多的坑,比如异步跨域请求在低版本的IE下需要用XDomainRequest对象来实现。

posted @ 2017-01-08 11:21  思梦PHP  阅读(1355)  评论(0编辑  收藏  举报