`

spring mvc处理 跨域问题

阅读更多

跨域问题

Edit

 

一、概念

       1、跨域:

              是指浏览器对于javascript的同源策略的限制。换句话说这个就是同源策略的保护机制。

              例如a.cn下面的js不能调用b.cn中的js对象或数据(因为a.cn和b.cn是不同域),所以跨域就出现了。

       2、同源策略:

              是指在JS的Ajax请求协议、IP/域名、端口这三项与浏览器上的url地址完全相同,则满足同源策略,既不会出现跨域问题。

 

 列举一些跨域请求,如下:

演示:http://study.cn/json/jsonp/jsonp.html
 请求地址  形式  结果
http://study.cn/test/a.html 同一域名,不同文件夹  成功
http://study.cn/json/jsonp/jsonp.html 同一域名,统一文件夹  成功
http://a.study.cn/json/jsonp/jsonp.html 不同域名,文件路径相同  失败
 http://study.cn:8080/json/jsonp/jsonp.html  同一域名,不同端口  失败
https://study.cn/json/jsonp/jsonp.html  同一域名,不同协议    失败
 
 
 
 
 

二、突破跨域限制的解决方案

           1、 跨域源资源共享(CORS):

              CORS即Cross Origin Resource Sharing(跨域源资源共享),通俗说就是我们所熟知的跨域请求。众所周知,在以前,跨域可以采用代理、JSONP等方式,而在Modern浏览器面前,这些终将成为过去式,因为有了CORS。

              CORS在最初接触的时候只大概了解到,通过服务器端设置Access-Control-Allow-Origin响应头,即可使指定来源像访问同源接口一样访问跨域接口,最近在使用CORS的时候,由于需要传输自定义Header信息,发现原来CORS的规范定义远不止这些。

              CORS可以分成两种:

                   1、简单请求

                          HEAD、GET、POST

                         这类简单请求,只需要一次请求,后端响应的head部分携带一下信息就可以通过

                          Access-Control-Allow-Origin:*

                          Access-Control-Allow-Methods: HEAD,GET,POST

                          Access-Control-Max-Age: 3600

                          Access-Control-Expose-Headers:Origin, X-Requested-With, Content-Type, Accept

                          当你需要访问额外的信息时,就需要在 Access-Control-Expose-Headers 这一项当中填写并以逗号进行分隔。
                 

                   2、复杂请求

                          PUT,PATCH, DELETE, OPTIONS等

                        这类复杂的跨域问题,表面上看起来和简单请求使用上差不多,但实际上浏览器发送了不止一个请求。

                                1、首先,发送的是一种OPTIONS的"预请求",单服务端返回"预回应"结果为通过(告诉前端我是否允许你跨域访问某资源)

                                2、 然后,发送最终想要发送的跨域资源请求。

                          预请求实际上是对服务端的一种权限请求的询问,只有当预请求通过,前端才会实际发送最终的请求。

                          这类复杂请求,需要最少一次以上的请求,后端响应的head部分携带一下信息才可以通过。

                          Access-Control-Allow-Origin:*

                          Access-Control-Allow-Methods: PUT,PATCH,DELETE,OPTIONS

                          Access-Control-Max-Age: 3600

                          Access-Control-Expose-Headers:Origin, X-Requested-With, Content-Type, Accept

                          同理,当你需要访问额外的信息时,也需要在 Access-Control-Expose-Headers 这一项当中填写并以逗号进行分隔。Allow-Method中添加options和Expose-Headers添加Origin,都是为了后端正确响应"预请求"的。所以一定注意不要遗漏了,否则必然导致复杂跨域请求不成功。

 

三、跨域问题解决方案

            Spring MVC 4.2版本后提供了完善的跨域解决方案,具体实体方式如下:

            1、application.xml 添加如下配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd  
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd  
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd"
    default-lazy-init="false">

    <mvc:annotation-driven />

    <mvc:cors>
        <mvc:mapping path="/**" allowed-origins="*"
            allowed-methods="GET, POST, PUT, PATCH, DELETE, OPTIONS"
            allowed-headers="ticket,digest,Origin,Accept,Content-Type,X-Requested-With,Transfer-Encoding,Date,status,Server"
            exposed-headers="ticket,digest,Origin,Accept,Content-Type,X-Requested-With,Transfer-Encoding,Date,status,Server"
            allow-credentials="true" max-age="3600" />
    </mvc:cors>
</beans>

 
 
 
 
 
 
 
 
 
 

            2、web.xml 添加如下配置,作用是开启OPTIONS请求,因为默认SpringMVC是关闭了OPTIONS请求的。

<!-- springMvc -->
    <servlet>
        <servlet-name>springMvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>dispatchOptionsRequest</param-name>
            <param-value>true</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics