什么是跨域?和跨域的解决方案

一、跨域的由来

         跨域大家都不陌生,跨域是为了克服浏览器的同源策略。但可能对浏览器为什么会出同源策略有些陌生。这里先简单介绍跨域的由来。

        浏览器的同源策略是为了限制CSRF攻击,因为我们有些场景确实需要,访问不同域名下的资源,所以需要跨域。所以就出现了各种跨域的方式,如JSONP、CORS、H5的postMessage、Nginx等方式,本文住要介绍JSONP和CORS。

 

二、CSRF

1、CSRF是什么?

         CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。它在 2007 年曾被列为互联网 20 大安全隐患之一。

2CSRF可以做什么?

        你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。

攻击示例如下:

                            

3、模拟代码:

①、访问网站A,首先用户登录,代码如下

<form aciton="" method="post">
	<input type="text" name="account">
	<input type="password" name="password">
<form>

然后生成一个包含登录信息的cookie

②、用户可以在网站A转账:

<form method="post" id="form">
   <input type="text" name="money" id="money">//转账的金额
   <input type="text" name="receiver" id="receiver">//收款人
   <input type="submit" value="确认">
</form>

③、用户访问B网站,此时B网站Cookie没有过期。

$(“#money”).val(100000);
$(“# receiver”).val(“黑客”);

$.ajax({
    type: "POST",
    cache: false,
    url:  "网站地址",
    data: $("form").serialize(),
    dataType: "json",
    success: function (data) {
      , error: function () {
    }
});	

这样用户A在不知情的情况下,钱丢了。

三、浏览器的同源策略

        为了防止CSRF攻击,浏览器村的大佬们,想出了通过HTTP Referer验证,是否是来自同一个网站。 同源包括要求协议相同、域名相同、端口相同。有任何一个不同则认为不同。

       现在大型网站中html、js、css、image等放置在不同的服务器的需求。所以浏览器进行了一点妥协,img script style等标签,都允许垮域引用资源,严格说这都是不符合同源要求的。

      JSON正是利用了浏览器的这点妥协而产生的。

四、JSOP介绍

       首先我们需要明白,在页面上直接发起一个跨域的ajax请求是不可以的,但是,在页面上引入不同域上的js脚本却是可以的,就像你可以在自己的页面上使用<img src=""> 标签来随意显示某个域上的图片一样。比如我在8080端口的页面上请求一个9090端口的图片:可以看到直接通过src跨域请求是可以的。

1、使用<script>标签跨域:

①、localhost:8080  访问获取 localhost:9090 的数据 就属于跨域。

②、script 跨域:

        当点击"跨域获取数据"的按钮时,添加一个<script>标签,用于发起跨域请求;注意看请求地址后面带了一个callback=showData的参数;

  showData即是回调函数名称,传到后台,用于包裹数据。数据返回到前端后,就是showData(result)的形式,因为是script脚本,所以自动调用showData函数,而result就是showData的参数。

至此,我们算是跨域把数据请求回来了,但是比较麻烦,需要自己写脚本发起请求,然后写个回调函数处理数据,不是很方便。

代码如图

                         

                         

2、使用jquery的jsonp方式跨域请求

        服务端代码不变,js代码如下:最简单的方式,只需配置一个dataType:'jsonp',就可以发起一个跨域请求。jsonp指定服务器返回的数据类型为jsonp格式,可以看发起的请求路径,自动带了一个callback=xxx,xxx是jquery随机生成的一个回调函数名称。

        这里的success就跟上面的showData一样,如果有success函数则默认success()作为回调函数。也可以自己指定函数,jsonpCallback: "showData" 。

                     

                    

问题:post不支持 Jsonp 为什么?

总结:jQuery ajax方式以jsonp类型发起跨域请求,其原理跟<script>脚本请求一样,因此使用jsonp时也只能使用GET方式发起跨域请求。跨域请求需要服务端配合,设置callback,才能完成跨域请求。

五、CORS实现跨域

1什么是CORS

    Cross-Origin Resource Sharing(CORS)跨来源资源共享是一份浏览器技术的规范,提供了 Web 服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略,是 JSONP 模式的现代版。

CORS是W3C工作草案,它定义了在跨域访问资源时浏览器和服务器之间如何通信。

2、CORS 对比 JSONP

①、都能解决 Ajax直接请求普通文件存在跨域无权限访问的问题

②、JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求

③、使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理

④、JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS

3、CORS 实现思路

CORS背后的基本思想是使用自定义的HTTP头部允许浏览器和服务器相互了解对方,从而决定请求或响应成功与否

4、CORS 几种解决方案

①:简单的自定义CORSFilter / Interceptor

                       

②、有开源jar包支持

③、SpringMvc支持

  1. 注解方式

Controller类或其方法上加@CrossOrigin注解,来使之支持跨域。如下

            @CrossOrigin(origins = "*", maxAge = 3600)

            @CrossOrigin(origins="http://test.com",maxAge=3600)

 

        2) 配置文件支持,在SpringMVC配置文件中添加下面代码

<mvc:cors>
         <mvc:mapping path="/**" allowed-origins="*" allow-credentials="true"  max-age="1800" allowed-methods="GET,POST"/>

</mvc:cors>

 

 

猜你喜欢

转载自blog.csdn.net/luoyeyeyu/article/details/83096726