问题:当1.1.1.1:80访问1.1.1.1:8080时,按照以下抄来的配置并不能实现跨域
@Slf4j
@Configuration
public class GlobalCorsConfig {
public static CorsConfiguration addCorsConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
//请求常用的三种配置,*代表允许所有,当时你也可以自定义属性(比如header只能带什么,只能是post方式等等)
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
log.info("跨域配置:允许");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", addCorsConfig());
return new CorsFilter(source);
}
}
原因:org.springframework.web.filter.CorsFilter.DefaultCorsProcessor.processRequest()该方法在端口号不一样时仍视为同源请求,所以不会设置跨域请求头,DefaultCorsProcessor.processRequest的部分源码↓↓↓
解决方法:重新实现一个CorsFilter,注释掉isSameOrigin方法,简单粗暴
package com.zyd.shiro.framework.config;
import org.apache.shiro.web.servlet.OncePerRequestFilter;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.*;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class MyCorsFilter extends OncePerRequestFilter {
private static CorsProcessor processor;
static {
processor = new DefaultCorsProcessor() {
private boolean responseHasCors(ServerHttpResponse response) {
try {
return (response.getHeaders().getAccessControlAllowOrigin() != null);
} catch (NullPointerException npe) {
return false;
}
}
@Override
@SuppressWarnings("resource")
public boolean processRequest(@Nullable CorsConfiguration config, HttpServletRequest request,
HttpServletResponse response) throws IOException {
if (!CorsUtils.isCorsRequest(request)) {
return true;
}
ServletServerHttpResponse serverResponse = new ServletServerHttpResponse(response);
if (responseHasCors(serverResponse)) {
return true;
}
// 注释源码中判断同源方法
// 不注释时:localhost:80与localhost:8080是同源请求,不添加跨域请求头
ServletServerHttpRequest serverRequest = new ServletServerHttpRequest(request);
// if (WebUtils.isSameOrigin(serverRequest)) {
// return true;
// }
boolean preFlightRequest = CorsUtils.isPreFlightRequest(request);
if (config == null) {
config = new CorsConfiguration();
//请求常用的三种配置,*代表允许所有,当时你也可以自定义属性(比如header只能带什么,只能是post方式等等)
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
config.setAllowCredentials(true);
}
return handleInternal(serverRequest, serverResponse, config, preFlightRequest);
}
};
}
protected void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
if (CorsUtils.isCorsRequest(req)) {
CorsConfiguration corsConfiguration = GlobalCorsConfig.addCorsConfig();
boolean isValid = processor.processRequest(corsConfiguration, req, res);
if (!isValid || CorsUtils.isPreFlightRequest(req)) {
return;
}
}
chain.doFilter(request, response);
}
}