SpringBoot项目跨域处理

159 阅读3分钟

这是我参与11月更文挑战的第5天,活动详情查看:[2021最后一次更文挑战]

前言

我的上一篇文章Idea搭建MybatisPlus+Druid+多数据源+自动化代码生成器 附源码!!嘛然后搭建完了肯定得后续怎样使用起来呀,所以接下来的一段实际可能都会围绕着这个项目进行周边更新。

跨域

往往一个后端项目搭建完成之后,那就得考虑后续的用途了如果是那种前后端分离的项目,可能在实际情况中就会出现跨域的问题,那么如何解决呢?

跨域

跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号(如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源浏览器中一个域名下面的某个请求到另外一个域名的时候,端口,域名,协议其中任意一个不同都会导致跨域,而一旦出现跨域,在请求等信息没有错的情况下大部分都是后端或者服务器端解决的,好比在代码中配置一些允许访问代码,当然springBoot也有注解的方式,还有就是可以在被访问的服务器配置跨域允许 like negix 设置请求header.

解决方式

1. 全局跨域处理

package com.smile.ssm.common;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author Smile
 * @version v1.0
 * @description 全局跨域处理配置类
 * @time 2021/11/25 14:32
 */
@Configuration
public class CorsConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer(){
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedHeaders("*")
                        .allowedMethods("*")
                        .allowedOrigins("*");
            }
        };
    }
}

2. @CrossOrigin 注解处理

image.png 项目直接在对应的api上添加相应的注解

3. webFilter处理

package com.smile.ssm.filter;

import com.smile.ssm.cons.HttpCons;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Smile
 * @version v1.0
 * @description TODO
 * @time 2021/11/25 14:37
 */
@Component
public class WebFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {
        //log.info("----------------过滤器初始化------------------------");
    }


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        settCors(request, response);
        //如果是OPTIONS请求就return 往后执行会到业务代码中 他不带参数会产生异常
        if (request.getMethod().equals(HttpCons.OPTIONS)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        //白名单不拦截
        filterChain.doFilter(servletRequest, servletResponse);
    }


    @Override
    public void destroy() {

    }

    private void settCors(HttpServletRequest request, HttpServletResponse response) {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, X-Custom-Header,at,tid");
        //添加请求头 给前端获取文件流名称
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Access-Control-Allow-Credentials", "true");
    }
}

这个我粘贴出来的目的是因为我们能够更好的理解:

image.png 相信有过py或者爬取数据经验的小伙伴不会不理解的对吧。

4. nginx

location / {  
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

    if ($request_method = 'OPTIONS') {
        return 204;
    }
} 

当遇见问题的时候 可以先进行 1 2 4 测试

以上就是我所知的跨域解决方式!

END

自己的项目前端部分还没有开始,慢慢来吧,fighting!!! 项目源码地址:gitee.com/smile_lx/ss…