zoukankan      html  css  js  c++  java
  • SpringBoot设置跨域的几种方式

    什么是跨域?

      浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域 

    原因:

      由于浏览器的同源策略, 即a网站只能访问a网站的内容,不能访问b网站的内容.

    注意:

      跨域问题只存在于浏览器,也就是说当你的前端页面访问后端简单请求的接口时,返回值是有的,只是服务器没有在请求头指定跨域的信息,所以浏览器自动把返回值给"屏蔽了".

      经过上面的了解,可以得出几个解决跨域的方法(不考虑前端实现):

      1.服务端指定跨域信息

      2.在web页面与服务器之间加一层服务指定跨域信息,比如nginx
     

    使用springboot提供了跨域的方法:

      1.5版本为继承WebMvcConfigurerAdapter 类实现抽象方法,

    //springboot 1.5方式
    @Configuration
    public class WebMvcConfig extends WebMvcConfigurerAdapter {
     
      @Override
      public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedHeaders("*")
          .allowedMethods("*")
          .allowedOrigins("*")
          .allowCredentials(true);
      }
    }

    2.0以后为实现WebMvcConfigurer 接口重写方法

    //springboot 2.0以上的方式
    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
     
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedHeaders("Content-Type","X-Requested-With","accept,Origin","Access-Control-Request-Method","Access-Control-Request-Headers","token")
                    .allowedMethods("*")
                    .allowedOrigins("*")
                    .allowCredentials(true);
        }
    }

    使用拦截器实现跨域:

    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
     
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new HandlerInterceptor() {
                @Override
                public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                    response.addHeader("Access-Control-Allow-Origin", "*");
                    response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
                    response.addHeader("Access-Control-Allow-Headers",
                            "Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,token");
                    return true;
                }
     
                @Override
                public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
     
                }
     
                @Override
                public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
     
                }
            });
        }
     
    }

    注意:

    请求头中自定义的字段是不允许跨域的,所以要指定

    response.addHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,token");

    或者

    response.addHeader("Access-Control-Allow-Headers", "*");

    还可以使用servlet提供的过滤器进行跨域配置:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    /**
     * 请求的基本过滤器 预处理请求头
     */
    @Component
    @WebFilter(urlPatterns = {"/*"}, filterName = "tokenAuthorFilter")
    public class TokenAuthorFilter implements Filter {
    
        private static Logger LOG = LoggerFactory.getLogger(TokenAuthorFilter.class);
    
        @Override
        public void destroy() {
    
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response,
                             FilterChain chain) throws IOException, ServletException {
            HttpServletRequest req = (HttpServletRequest) request;
            HttpServletResponse rep = (HttpServletResponse) response;
    
            HttpSession session = req.getSession();
            LOG.info("sessionId:{}", session.getId());
            //LOG.info("Origin:{}", req.getHeader("Origin"));
    
            //设置允许跨域的配置
            // 这里填写你允许进行跨域的主机ip(正式上线时可以动态配置具体允许的域名和IP)
            rep.setHeader("Access-Control-Allow-Origin", "*");
            //rep.setHeader("Access-Control-Allow-Origin", "*");
            rep.setHeader("Access-Control-Expose-Headers", jwtProperties.getHeader());
            // 允许的访问方法
            rep.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE, PATCH");
            // Access-Control-Max-Age 用于 CORS 相关配置的缓存
            rep.setHeader("Access-Control-Max-Age", "3600");
            rep.setHeader("Access-Control-Allow-Headers", "token, Origin, X-Requested-With, Content-Type, Accept");
            //若要返回cookie、携带seesion等信息则将此项设置我true
            rep.setHeader("Access-Control-Allow-Credentials", "true");
            // 把获取的Session返回个前端Cookie
            //rep.addCookie(new Cookie("JSSESIONID", session.getId()));
            chain.doFilter(req, rep);
    
        }
    
        @Override
        public void init(FilterConfig arg0) throws ServletException {
    
        }
    
    }

    灵活的跨域方式:

      如果我们只想提供一个方法可以跨域,那么可以使用注解的形式:

    @CrossOrigin
    @RestController
    public class TestController {
    
    }
  • 相关阅读:
    二级菜单jquery
    js二级导航
    append appendChild appendTo区别
    cssText在 IE6/7/8和chrome/Firefox/IE9+的不同
    cssText
    css slice和splice
    js字符串函数之substring() substr()
    js字符串函数之split()join()
    Python面向对象之:三大特性:继承,封装,多态以及类的约束
    Python3 面向对象之:多继承
  • 原文地址:https://www.cnblogs.com/ifindu-san/p/10446325.html
Copyright © 2011-2022 走看看