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 {

}

原文地址:https://www.cnblogs.com/ifindu-san/p/10446325.html

时间: 2024-11-05 20:39:22

SpringBoot设置跨域的几种方式的相关文章

php跨域的几种方式

PHP实现跨域的几种形式 1.JSONP(JSON with padding)原理 利用html里面script标签可以加载其他域下的js这一特性,使用script src的形式来获取其他域下的数据,但是,因为是通过标签引入的,所以,会将请求到的JSON格式的数据作为js去运行处理,显然这样运行是不行的. 因此,就需要提前将返回的数据包装一下,封装成函数进行运行处理,函数名通过接口传参的方式传给后台,后台解析到函数名后在原始数据上包裹这个函数名,发送给前端.(JSONP 需要对应接口的后端的配合

解决浏览器跨域的几种方式

1.什么是跨域问题 在页面中使用js访问其他网站的数据时,就会出现跨域问题,比如在网站中使用ajax请求其他网站的天气.快递或者其他数据接口时,以及hybrid app中请求数据,浏览器会提     示一下错误: XMLHttpRequest cannot load http://你请求的域名. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://当前页的域  

关于跨域,以及跨域的几种方式

首先我们来想一想 为什么会有跨域这个名词的出现呢? 跨域又是什么呢?为何要跨域? 浏览器的同源策略又是什么?怎么解决? jsonp又是什么? 跨域的原理又是什么呢? 名词解释: 跨域: 浏览器对于javascript的同源策略的限制,例如a.cn下面的js不能调用b.cn中的js,对象或数据(因为a.cn和b.cn是不同域),所以跨域就出现了. 上面提到的,同域的概念又是什么呢??? 简单的解释就是相同域名,端口相同,协议相同 同源策略: 请求的url地址,必须与浏览器上的url地址处于同域上,

深入浅出:了解jsonp跨域的九种方式

什么是“”跨域”: 跨域访问,简单来说就是 A 网站的 javascript 代码试图访问 B 网站,包括提交内容和获取内容.由于安全原因,跨域访问是被各大浏览器所默认禁止的.当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还可以跨网分配文件和打印机等设备资源,使不同的域之间实现网络资源的共享与管理.这就形成了“跨域”. 广义的跨域: 1.) 资源跳转: A链接.重定向.表单提交2.) 资源嵌入: <link>.<script>.<img>.&l

ajax处理跨域有几种方式?实现原理是什么?

一.什么是跨域 我们先回顾一下域名地址的组成: http:// www . google : 8080 / script/jquery.js   http:// (协议号) www  (子域名) google (主域名) 8080 (端口号) script/jquery.js (请求的地址) * 当协议.子域名.主域名.端口号中任意一各不相同时,都算不同的“域”. * 不同的域之间相互请求资源,就叫“跨域”. 比如:http://www.abc.com/index.html 请求 http://

跨域的几种方式

一.什么是跨域 由于浏览器同源策略,凡是发送请求的url的协议.域名.端口三者之间任意一与当前页面地址不同即为跨域: 我们先回顾一下域名地址的组成: http:// www . google : 8080 / script/jquery.js  http:// (协议号) www  (子域名) google (主域名) 8080 (端口号) script/jquery.js (请求的地址) * 当协议.子域名.主域名.端口号中任意一各不相同时,都算不同的“域”. * 不同的域之间相互请求资源,就

浅谈跨域的N种方式

奇葩方式:谷歌浏览器添加属性 --disable-web-security 邮件chrome浏览器,切换到快捷tab,在目标框追加--disable-web-security,如果目标URL带双引号,则追加--args --disable-web-security,重启浏览器会提示”不受支持的disable-web-security属性“,表示修改已生效. HTML5方式,后台设置相应头 Access-Control-Allow-Origin 常规方式:jsonp,代理proxy

什么是跨域 &amp; 跨域的3种解决方案

所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)端口号(port) 同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源. 同源策略是浏览器安全的基石 同源策略会阻止一个域的 javascript 脚本和另外一个域的内容进行交互.例如办公内外网环境,当我们访问外网一个恶意网站的时候,恶意网站就会利用我们的主机向内网的 url 发送 ajax 请求,破坏或盗取数据 一.浏览器的非同源限制以及3种解决思路 非同源限制 无

前端跨域问题各种解决方式及原理

跨域的各种解决方式及原理 因为浏览器有某些安全级别的限制,例如,同源策略,所以在进行浏览器端的web应用开发的时候,经常会遇到跨域问题. 同源策略:只有在同源的情况下(同域名,同协议,同端口)才能进行数据交互 跨域问题报错:XMLHttpRequest cannot load https://api.douban.com/v2/movie/in_theaters. No 'Access-Control-Allow-Origin' header is present on the requeste