一、什么是跨域
同源策略是浏览器一个重要的安全策略,所谓的同源就是指两个域有相同的协议(protocol)、域名(host)、端口(port),这三者之间任何一个不同都会构成跨域的情况,比如说前后端分离之后,前后都在两个域之下,前端的浏览器请求后端服务器的数据的时候就需要做跨域处理。
非同源的限制
- 无法读取非同源网页的 Cooike、LocalStorage、IndexedDB
- 无法接触非同源网页的DOM
- 无法向非同源地址发送AJAX请求
二、什么情况下需要解决跨域
比如在ThingJS-X中,在【业务配置】-【图表编辑】下,编辑图表时,如下图所示:
在下面填写接口地址的时候,如果配置的是第三方的接口地址,此时若不处理跨域请求,就可能报如下错误,这种情况下就需要解决跨域问题。
三、如何解决跨域
1、接口提供方自行解决(例如java后台)
(1)使用Filter过滤器解决
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.FilterConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.annotation.WebFilter;
- import javax.servlet.http.HttpServletResponse;
-
- @WebFilter(filterName= "CorsFilter", urlPatterns="*.do")
- public class CorsFilter implements Filter{
- @Override
- public void destroy() {
- }
- @Override
- public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
- HttpServletResponse response = (HttpServletResponse) resp;
- //解决跨域访问报错
- response.setHeader("Access-Control-Allow-Origin", "*");
- chain.doFilter(req, resp);
- }
- @Override
- public void init(FilterConfig arg0) throws ServletException {
- }
- }
复制代码- 注意:
- @WebFilter需要在启动类上添加上@ServletComponentScan注解才能被扫描到。
- response.setHeader("Access-Control-Allow-Origin", "*")中,*代表允许所有域发过来请求,如果想加以限制,可以配置具体到某个域名。
(2)解决跨域问题springboot所需配置
使用注解的形式配置org.springframework.web.filter.CorsFilter,通常springboot项目多数使用这种方式。
- import org.springframework.web.filter.CorsFilter;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.cors.CorsConfiguration;
- import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-
- /**
- * 解决跨域问题springboot所需配置
- */
- @Configuration
- public class CORSConfiguration {
- @Bean
- public CorsFilter corsFilter() {
- //1.添加CORS配置信息
- CorsConfiguration config = new CorsConfiguration();
- //1) 允许的域,不要写*,否则cookie就无法使用了
- config.addAllowedOrigin("*");
- config.addAllowedHeader("*");
- // 允许任何头
- config.addAllowedMethod("*");
- // 允许任何方法(post、get等)
- //2) 是否发送Cookie信息
- config.setAllowCredentials(true);
- //3) 允许的请求方式
- config.addAllowedMethod("OPTIONS");
- config.addAllowedMethod("HEAD");
- config.addAllowedMethod("GET");
- config.addAllowedMethod("PUT");
- config.addAllowedMethod("POST");
- config.addAllowedMethod("DELETE");
- config.addAllowedMethod("PATCH");
-
- // 4)允许的头信息
- config.addAllowedHeader("*");
-
- // 5)配置有效时长
- config.setMaxAge(3600*24L);
-
- //2.添加映射路径,我们拦截一切请求
- UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
- configSource.registerCorsConfiguration("/**", config);
- //3.返回新的CorsFilter.
- return new CorsFilter(configSource);
- }
- }
复制代码 2、通过配置nginx解决跨域问题
有时候在浏览器访问应用程序时,中间会有nginx作为代理转发浏览器的请求,此时我们就需要在nginx端解决跨域访问的问题。 只需要在Nginx的配置文件中配置以下参数: - location /thing {
- if ($request_method = 'OPTIONS') {
- add_header Access-Control-Allow-Origin * always;
- add_header Access-Control-Allow-Methods 'GET,POST,PUT,DELETE,OPTIONS';
- add_header Access-Control-Allow-Headers 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
- return 200;
- }
- add_header Access-Control-Allow-Origin '*' always;
- add_header Access-Control-Allow-Methods 'GET, PUT, POST, DELETE, OPTIONS';
- add_header Access-Control-Allow-Headers 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
- proxy_pass http://ip:port/thing;
- }
复制代码解释: 1. Access-Control-Allow-Origin 服务器默认是不被允许跨域的。给Nginx服务器配置`Access-Control-Allow-Origin *`后,表示服务器可以接受所有的请求源(Origin),即接受所有跨域的请求。 2. Access-Control-Allow-Headers 是为了防止出现以下错误: Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response. 这个错误表示当前请求Content-Type的值不被支持。其实是我们发起了"application/json"的类型请求导致的。 3. Access-Control-Allow-Methods 是为了防止出现以下错误: Content-Type is not allowed by Access-Control-Allow-Headers in preflight response. 4.给OPTIONS添加200的返回,是为了处理在发送POST请求时Nginx依然拒绝访问的错误 发送"预检请求"时,需要用到方法 OPTIONS ,所以服务器需要允许该方法。
|