什么是跨域以及几种简单解决方案

31 篇文章 0 订阅
26 篇文章 0 订阅

实际应用项目:http://github.crmeb.net/u/long

什么是跨域?

要明白什么是跨域之前,首先要明白什么是同源策略

同源策略就是用来限制从一个源加载的文档或脚本与来自另一个源的资源进行交互。那怎样判断是否是同源呢?

如果协议,端口(如果指定了)和主机对于两个页面是相同的,则两个页面具有相同的源,也就是同源。也就是说,要同时满足以下3个条件,才能叫同源:

  1. 协议相同
  2. 端口相同
  3. 主机相同

举个例子就一目了然了:

我们来看下面的页面是否与 http://store.company.com/dir/index.html 是同源的?

  1. http://store.company.com/dir/index2.html 同源
  2. http://store.company.com/dir2/index3.html 同源 虽然在不同文件夹下
  3. https://store.company.com/secure.html 不同源 不同的协议(https)
  4. http://store.company.com:81/dir/index.html 不同源 不同的端口(81)
  5. http://news.company.com/dir/other.html 不同源 不同的主机(news)

所以当面对跨域问题的时候,有什么解决方案呢?

跨域的几种解决方案

document.domain方法

我们来看一个具体场景:有一个页面 http://www.example.com/a.html ,它里面有一个iframe,这个iframe的源是 http://example.com/b.html ,很显然它们是不同源的,所以我们无法在父页面中操控子页面的内容。

解决方案如下:

<!-- b.html -->
<script>
document.domain = 'example.com';
</script>
<!-- a.html -->
<script>
document.domain = 'example.com';
var iframe = document.getElementById('iframe').contentWindow.document;

//后面就可以操作iframe里的内容了...

</script>

所以我们只要将两个页面的document.domain设置成一致就可以了,要注意的是,document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域。

但是,这种方法只能解决主域相同的跨域问题。

window.name方法

window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。

我们来看一个具体场景,在一个页面 example.com/a.html 中,我们想获取 data.com/data.html 中的数据,以下是解决方案:

<!-- data.html -->
<script>
window.name = 'data'; //这是就是我们需要通信的数据
</script>
<!-- a.html -->
<html>
<head>
<script>
    function getData () {
        var iframe = document.getElementById('iframe');
        iframe.src = 'example.com/b.html'; // 这里让iframe与父页面同源
        
        iframe.onload = function () {
            var data = iframe.contentWindow.name; //在这里我们得到了跨域页面中传来的数据
        };
    }
</script>
</head>
<body>
</body>
</html>

JSONP方法

JONSP(JSON with Padding)是JSON的一种使用模式。基本原理如下:

<!-- a.html -->
<script>
    function dealData (data) {
        console.log(data);
    }
</script>

<script src='http://example.com/data.php?callback=dealData'></script>
<?php
    $callback = $_GET['callback'];
    $data = 'data';
    echo $callback.'('.json_encode($data).')';
?>

这时候在a.html中我们得到了一条js的执行语句dealData('data'),从而达到了跨域的目的。

所以JSONP的原理其实就是利用引入script不限制源的特点,把处理函数名作为参数传入,然后返回执行语句,仔细阅读以上代码就可以明白里面的意思了。

如果在jQuery中用JSONP的话就更加简单了:

<script>
$.getJSON(''http://example.com/data.php?callback=?', function (data) {
    console.log(data);
});
</script>

注意jQuery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用JSONP的回调函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
解决 Geoserver 请求跨域几种思路如下: 1. 使用代理服务器:可以使用一个代理服务器来处理跨域请求。代理服务器可以在客户端和 Geoserver 之间充当中间人,将客户端的请求转发给 Geoserver,并将 Geoserver 的响应返回给客户端。这种方法可以通过配置代理服务器来实现跨域请求,但是会增加服务器的负担。 2. 配置 Geoserver:Geoserver 本身支持 CORS(Cross-Origin Resource Sharing),可以通过在 Geoserver 的 web.xml 文件中配置 CORS 的参数来实现跨域请求。可以通过添加以下代码来启用 CORS: ``` <filter> <filter-name>CorsFilter</filter-name> <filter-class>org.apache.catalina.filters.CorsFilter</filter-class> <init-param> <param-name>cors.allowed.origins</param-name> <param-value>*</param-value> </init-param> </filter> <filter-mapping> <filter-name>CorsFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` 3. 使用 JSONP:JSONP(JSON with Padding)是一种跨域请求的解决方案。它通过在请求中添加一个回调函数名,让服务器返回一个 JavaScript 函数调用,从而绕过浏览器的跨域限制。如果 Geoserver 支持返回 JSONP 格式数据,可以通过在客户端使用 JSONP 的方式来实现跨域请求。 4. 使用 WebSocket:WebSocket 是一种支持双向通信的网络协议,可以在客户端和服务器之间建立一个持久化的连接。如果 Geoserver 支持 WebSocket ,可以通过 WebSocket 的方式来实现跨域请求。这种方法相对于其他方法更加灵活,但需要客户端和服务器都支持 WebSocket 协议。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值