使用拦截器解决跨域问题

使用拦截器解决跨域问题

1.跨域

**跨域问题(CORS)是指在浏览器中,当一个网页向不同域名(域、协议或端口)**发送请求时,如果目标资源的响应未包含适当的跨域头信息,浏览器会阻止该请求,以保护用户数据的安全。

**同源策略(Same-Origin Policy)**是浏览器的一项安全机制,它限制了一个网页只能从同一来源加载其他资源,即源自相同协议、域名和端口的资源。这种限制是为了防止恶意网站通过跨域请求获取用户的敏感信息。

当网页需要从其他域名请求数据时(例如通过 AJAX 请求或通过 <img><script> 等标签加载资源),浏览器会发送一个跨域请求。这时,浏览器会向目标服务器发送一个预检请求(OPTIONS 请求)来获取服务器是否允许跨域访问的权限。如果服务器响应中包含了适当的跨域头信息(如 Access-Control-Allow-Origin),浏览器会允许请求继续并获取响应数据。否则,浏览器将拦截该请求,JavaScript 代码将无法访问响应数据。

2.解决办法

解决跨域问题的常见方法包括:

  1. 在服务器端设置适当的跨域头信息,允许指定的域名进行跨域访问。
  2. 使用代理服务器,将跨域请求发送到同一域名下,然后由代理服务器转发请求并返回响应。
  3. 使用 JSONP(JSON with Padding)来进行跨域请求,JSONP 利用 <script> 标签不受同源策略限制的特性来获取跨域数据。
  4. 使用 WebSocket 进行双向通信,WebSocket 不受同源策略的限制。
  5. 在某些情况下,使用跨域资源共享(CORS)的凭证(Credentials)模式,可以发送包含凭证的跨域请求。

需要注意的是,跨域问题只存在于浏览器环境中,服务器之间的通信不受同源策略的限制。

3.使用拦截器解决跨域问题

3.1 方案一

3.1.1定义拦截器
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public class MyInteceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String origin = request.getHeader("Origin");
        log.info("origin: {}", origin);
        response.setHeader("Access-Control-Allow-Origin", origin);
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization,Access-Token,token");
        response.setHeader("Access-Control-Expose-Headers", "*");//响应客户端的头部 允许携带Token 等等
        response.setHeader("Access-Control-Allow-Credentials", "true");  // 允许携带cookie
        response.setHeader("Access-Control-Max-Age", "3600");   // 预检请求的结果缓存时间
        return true;
    }
}

3.1.2 注册拦截器
package com.lhc.config;

import com.lhc.interceptors.MyInteceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInteceptor()).excludePathPatterns("/webjars/**", "/swagger-resources/**", "/doc.html").addPathPatterns("/**");
    }
}

3.2 方案二

3.2.1定义拦截器
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
public class MyInteceptor implements HandlerInterceptor {
}

3.2.2 配置跨域资源共享(CORS)的映射规则
import com.lhc.interceptors.MyInteceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*") //2.4.0版本后的写法
                .allowCredentials(true)
                .allowedMethods("*")
                .allowedHeaders("*");
    }
}

3.2.3 报错
java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*"since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a set of origins, list them explicitly or consider using "allowedOriginPatterns" instead.

解决方案

SpringBoot升级到2.4.0版本之后,跨域配置中的.allowedOrigins不再可用,需要修改为:.allowedOriginPatterns

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值