springmvc源码学习(二十八)解决跨域的几种方式


前言


一、跨域

是由于浏览器的同源策略限制,同源策略是一个重要的安全策略,会阻止一个域的javascript脚本和另外一个域的内容进行交互。一个请求url的协议(protocol)、域名(host)、端口(port)都要相同,其中有一个不同都会产生跨域问题。

二、解决

1、CorsFilter

(1)自定义 CustomCorsFilter

public class CustomCorsFilter extends CorsFilter {
    private CorsProps corsProps;

    public CustomCrosFilter(CorsConfigurationSource configSource, CorsProps corsProps) {
        super(configSource);
        this.corsProps = corsProps;

    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {


        response.setHeader("Access-Control-Allow-Origin", corsProps.getOrigin());
        response.setHeader("Access-Control-Allow-Credentials", corsProps.getCredentials());
        response.setHeader("Access-Control-Allow-Methods", corsProps.getMethods());
        response.setHeader("Access-Control-Allow-Headers", corsProps.getHeaders());
        filterChain.doFilter(request, response);
    }

(2)CorsProps

@ConfigurationProperties(prefix = "cors")
@Data
public class CorsProps {
    private String origin = "*";
    private String credentials = "true";
    private String methods = "POST, GET, PUT, DELETE, OPTIONS";
    private String headers = "Content-Type, Data-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, Accept, DataType, responseType";
    private String maxAge = "300";
}

(3)CorsAutoConfiguration

@Configuration
@ConditionalOnProperty(prefix = "cors",matchIfMissing = true,value = "enabled")
@Slf4j
public class CorsAutoConfiguration {
    @Autowired
    private CorsProps corsProps;

    @Bean
    public CustomCorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig());
        return new CustomCorsFilter(source,crosProps);
    }

    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        // Access-Control-Allow-Origin
        corsConfiguration.addAllowedOrigin(corsProps.getOrigin());
        corsConfiguration.addAllowedHeader(corsProps.getHeaders());
        // Access-Control-Allow-Methods
        corsConfiguration.addAllowedMethod(corsProps.getMethods());
        // 预检请求的有效期 Access-Control-Max-Age
        corsConfiguration.setMaxAge(Long.valueOf(corsProps.getMaxAge()));
        // 是否支持安全证书 Access-Control-Allow-Credentials
        corsConfiguration.setAllowCredentials(Boolean.valueOf(corsProps.getCredentials()));
        return corsConfiguration;
    }

    @Bean
    public FilterRegistrationBean corsFilterRegistrationBean(CustomCorsFilter corsFilter) {
        FilterRegistrationBean frb = new FilterRegistrationBean();
        //设置最高优先级
        frb.setOrder(Ordered.HIGHEST_PRECEDENCE);
        frb.setFilter(corsFilter);
        frb.addUrlPatterns("/*");
        frb.setName("customCorsFilter ");
        return frb;
    }

2、实现 WebMvcConfigurer

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

   @Autowired
    private CorsProps corsProps;
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(Boolean.getBoolean(corsProps.getCredentials()))
                .allowedOrigins(corsProps.getOrigin())
                .allowedMethods(corsProps.getMethods().split(","))
                .allowedHeaders(corsProps.getHeaders());
    }

}

3、实现 HandlerInterceptor

(1)CorsHandlerInterceptor

public class CorsHandlerInterceptor implements HandlerInterceptor {

    private CorsProps corsProps;

    public CorsHandlerInterceptor(CorsProps corsProps) {
        this.corsProps = corsProps;
    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        response.setHeader("Access-Control-Allow-Origin", corsProps.getOrigin());
        response.setHeader("Access-Control-Allow-Credentials", corsProps.getCredentials());
        response.setHeader("Access-Control-Allow-Methods", corsProps.getMethods());
        response.setHeader("Access-Control-Allow-Headers", corsProps.getHeaders());
       
        return true;
    }
}

(2)注册拦截器

@Configuration
public class CorsInterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private CorsProps corsProps;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加拦截器,配置拦截地址
        registry.addInterceptor(new CorsHandlerInterceptor(corsProps))
                .addPathPatterns("/**");;
    }
}

其他方式也可以实现,如通过 @CrossOrigin 进行更细粒度的控制跨域 ,通过 nginx 进行代理转发等。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
SpringMVC 提供了多种解决乱码问题的方式,主要有以下几种: 1. 在 web.xml 中添加过滤器:通过在 web.xml 中添加 CharacterEncodingFilter 过滤器,可以将请求和响应的编码都设置为 UTF-8。具体配置代码如下: ``` <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` 2. 在 SpringMVC 配置文件中设置编码过滤器:在 SpringMVC 配置文件中配置编码过滤器,也可以将请求和响应的编码设置为 UTF-8。具体配置代码如下: ``` <mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <constructor-arg value="UTF-8"/> </bean> </mvc:message-converters> </mvc:annotation-driven> ``` 3. 在 Controller 层中设置编码:在 Controller 层的方法中,可以通过 @RequestMapping 注解中的 produces 属性设置返回数据的编码格式。具体代码如下: ``` @RequestMapping(value = "/test", produces = "text/html;charset=UTF-8") @ResponseBody public String test() { return "测试中文乱码问题"; } ``` 总的来说,SpringMVC 提供了多种解决乱码问题的方式,开发者可以根据实际情况选择合适的方式进行配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_lrs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值