1. 跨域问题简介
还是要简单介绍一下跨域的原因——同源策略。 同源策略是浏览器上为安全性考虑实施的的安全策略。 两个页面地址中的协议、域名和端口号一致,则表示同源。 同源策略的限制:
存储在浏览器中的数据,如localStroage、Cookie和IndexedDB不能通过脚本跨域访问不能通过脚本操作不同域下的DOM不能通过ajax请求不同域的数据
所以,只要是请求不同 协议、域名和端口号 就会产生跨域的问题,这在前后端开发中是很常见的问题,我也是在写毕设中遇到了这个问题。
2. 解决原理
浏览器有同源策略,但是并不代表浏览器就不允许跨域的产生。
跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。
这是官方的解释,其实就是服务器告诉浏览器,哪些URl可以进行跨域访问
2. 三种解决方案
2.1 方案一: Filter
编写一个Filter
package com
.ken
.localserver
.filter
;
import javax
.servlet
.*
;
import javax
.servlet
.http
.HttpServletResponse
;
import java
.io
.IOException
;
public class CORSFilter implements Filter{
@Override
public void init(FilterConfig filterConfig
) throws ServletException
{
}
@Override
public void doFilter(ServletRequest servletRequest
, ServletResponse servletResponse
, FilterChain filterChain
) throws IOException
, ServletException
{
System
.out
.println("work");
HttpServletResponse response
= (HttpServletResponse
) servletResponse
;
response
.setHeader("Access-Control-Allow-Origin", "*");
response
.setHeader("Access-Control-Allow-Methods", "POST, GET");
response
.setHeader("Access-Control-Max-Age", "3600");
response
.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
filterChain
.doFilter(servletRequest
, servletResponse
);
}
@Override
public void destroy() {
}
}
然后在 web.xml 文件中配置该过滤器
<filter>
<filter-name>CORSFilter
</filter-name>
<filter-class>com.ken.localserver.filter.CORSFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>CORSFilter
</filter-name>
<url-pattern>/*
</url-pattern>
</filter-mapping>
2.2 方案二: @CrossOrigin
使用SpringMVC的@CrossOrigin注解来实现CORS 跨域
作用位置: @CrossOrigin可以作用在类、方法上
当作用在方法上时,是表示该方法拦截的URL能够跨域访问当作用在类上时,该类下所有URL都能够跨域访问
参数: 如果不写参数,就表示允许来自任意的源站以及任意 HTTP 请求方法的请求访问(这样不是非常好) @CrossOrigin(origins = “http://127.0.0.1:3000”, maxAge = 3600)
origins :表示来源,也就是前端请求的地址。 allowedHeaders :允许request携带的请求头。exposedHeaders :用户代理将允许客户端访问的响应头列表。(不是很清楚,知道的大佬可以评论一下)methods:请求的方式,例如:GET,POST,PUT,DELETE等。maxAge:缓存存储的最大时间。
2.3 方案三(推荐): <mvc:cors>
SpringMVC已经支持CORS(Spring MVC 版本必须是 4.2 及以上),我们只需要在SpringMVC的配置文件中进行一些配置即可。
像SpringMVC的配置文件中添加以下代码
<mvc:cors>
<mvc:mapping path="/**"
allowed-origins="http://localhost:3000,http://127.0.0.1:3000,http://localhost:9528,http://127.0.0.1:9528"
allowed-methods="GET,POST,PUT,POST,DELETE"
max-age="3600" />
</mvc:cors>
参数介绍:
path:能够跨域的路径,这个其实就相当于方法一中Filter拦截的路径。allowed-origins:表示来源,也就是前端请求的地址。allowed-methods:请求的方式,例如:GET,POST,PUT,DELETE等。max-age:缓存存储的最大时间。
完成配置后重启服务器,前端代码不需要改变