Springboot升级至2.4.0中出现的跨域问题分析及修改方案

问题

Springboot升级至2.4.0中出现的跨域问题。
在Springboot 2.4.0版本之前使用的是2.3.5.RELEASE,对应的Spring版本为5.2.10.RELEASE。
升级至2.4.0后,对应的Spring版本为5.3.1。
Springboot2.3.5.RELEASE时,我们可以使用CorsFilter设置跨域。

分析

版本2.3.5.RELEASE 设置跨域

设置代码如下:

@Configuration
public class ResourcesConfig implements WebMvcConfigurer {
  @Bean
  public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    // 允许访问的客户端域名
    config.addAllowedOrigin("*");
    // 允许服务端访问的客户端请求头
    config.addAllowedHeader("*");
    // 允许访问的方法名,GET POST等
    config.addAllowedMethod("*");
    // 对接口配置跨域设置
    source.registerCorsConfiguration("/**" , config);
    return new CorsFilter(source);
  }
}

是允许使用*设置允许的Origin。
这里我们看一下类CorsFilter的源码,5.3.x版本开始,针对CorsConfiguration新增了校验

5.3.x源码分析 CorsFilter

/**
 * {@link javax.servlet.Filter} to handle CORS pre-flight requests and intercept
 * CORS simple and actual requests with a {@link CorsProcessor}, and to update
 * the response, e.g. with CORS response headers, based on the policy matched
 * through the provided {@link CorsConfigurationSource}.
 *
 * <p>This is an alternative to configuring CORS in the Spring MVC Java config
 * and the Spring MVC XML namespace. It is useful for applications depending
 * only on spring-web (not on spring-webmvc) or for security constraints that
 * require CORS checks to be performed at {@link javax.servlet.Filter} level.
 *
 * <p>This filter could be used in conjunction with {@link DelegatingFilterProxy}
 * in order to help with its initialization.
 *
 * @author Sebastien Deleuze
 * @since 4.2
 * @see <a href="https://www.w3.org/TR/cors/" rel="external nofollow" >CORS W3C recommendation</a>
 * @see UrlBasedCorsConfigurationSource
 */
public class CorsFilter extends OncePerRequestFilter {

	private final CorsConfigurationSource configSource;

	private CorsProcessor processor = new DefaultCorsProcessor();

	/**
	 * Constructor accepting a {@link CorsConfigurationSource} used by the filter
	 * to find the {@link CorsConfiguration} to use for each incoming request.
	 * @see UrlBasedCorsConfigurationSource
	 */
	public CorsFilter(CorsConfigurationSource configSource) {
		Assert.notNull(configSource, "CorsConfigurationSource must not be null");
		this.configSource = configSource;
	}

	/**
	 * Configure a custom {@link CorsProcessor} to use to apply the matched
	 * {@link CorsConfiguration} for a request.
	 * <p>By default {@link DefaultCorsProcessor} is used.
	 */
	public void setCorsProcessor(CorsProcessor processor) {
		Assert.notNull(processor, "CorsProcessor must not be null");
		this.processor = processor;
	}

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

		CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);
		boolean isValid = this.processor.processRequest(corsConfiguration, request, response);
		if (!isValid || CorsUtils.isPreFlightRequest(request)) {
			return;
		}
		filterChain.doFilter(request, response);
	}

}

CorsFilter继承自OncePerRequestFilterdoFilterInternal方法会被执行。类中还创建了一个默认的处理类DefaultCorsProcessordoFilterInternal调用this.processor.processRequest
往下

processRequest

@Override
	@SuppressWarnings("resource")
	public boolean processRequest(@Nullable CorsConfiguration config, HttpServletRequest request,
			HttpServletResponse response) throws IOException {

		Collection<String> varyHeaders = response.getHeaders(HttpHeaders.VARY);
		if (!varyHeaders.contains(HttpHeaders.ORIGIN)) {
			response.addHeader(HttpHeaders.VARY, HttpHeaders.ORIGIN);
		}
		if (!varyHeaders.contains(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD)) {
			response.addHeader(HttpHeaders.VARY, HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD);
		}
		if (!varyHeaders.contains(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS)) {
			response.addHeader(HttpHeaders.VARY, HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS);
		}

		if (!CorsUtils.isCorsRequest(request)) {
			return true;
		}

		if (response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN) != null) {
			logger.trace("Skip: response already contains \"Access-Control-Allow-Origin\"");
			return true;
		}

		boolean preFlightRequest = CorsUtils.isPreFlightRequest(request);
		if (config == null) {
			if (preFlightRequest) {
				rejectRequest(new ServletServerHttpResponse(response));
				return false;
			}
			else {
				return true;
			}
		}

		return handleInternal(new ServletServerHttpRequest(request), new ServletServerHttpResponse(response), config, preFlightRequest);
	}

进入最后一行

handleInternal

/**
	 * Handle the given request.
	 */
	protected boolean handleInternal(ServerHttpRequest request, ServerHttpResponse response,
			CorsConfiguration config, boolean preFlightRequest) throws IOException {

		String requestOrigin = request.getHeaders().getOrigin();
		String allowOrigin = checkOrigin(config, requestOrigin);
		(省略...)
		response.flush();
		return true;
	}

查看方法checkOrigin

checkOrigin

@Nullable
	protected String checkOrigin(CorsConfiguration config, @Nullable String requestOrigin) {
		return config.checkOrigin(requestOrigin);
	}

Go on

checkOrigin

/**
	 * Check the origin of the request against the configured allowed origins.
	 * @param requestOrigin the origin to check
	 * @return the origin to use for the response, or {@code null} which
	 * means the request origin is not allowed
	 */
	@Nullable
	public String checkOrigin(@Nullable String requestOrigin) {
		if (!StringUtils.hasText(requestOrigin)) {
			return null;
		}
		if (!ObjectUtils.isEmpty(this.allowedOrigins)) {
			if (this.allowedOrigins.contains(ALL)) {
				validateAllowCredentials();
				return ALL;
			}
			for (String allowedOrigin : this.allowedOrigins) {
				if (requestOrigin.equalsIgnoreCase(allowedOrigin)) {
					return requestOrigin;
				}
			}
		}
		if (!ObjectUtils.isEmpty(this.allowedOriginPatterns)) {
			for (OriginPattern p : this.allowedOriginPatterns) {
				if (p.getDeclaredPattern().equals(ALL) || p.getPattern().matcher(requestOrigin).matches()) {
					return requestOrigin;
				}
			}
		}
		return null;
	}

方法validateAllowCredentials

validateAllowCredentials

/**
	 * Validate that when {@link #setAllowCredentials allowCredentials} is true,
	 * {@link #setAllowedOrigins allowedOrigins} does not contain the special
	 * value {@code "*"} since in that case the "Access-Control-Allow-Origin"
	 * cannot be set to {@code "*"}.
	 * @throws IllegalArgumentException if the validation fails
	 * @since 5.3
	 */
	public void validateAllowCredentials() {
		if (this.allowCredentials == Boolean.TRUE &&
				this.allowedOrigins != null && this.allowedOrigins.contains(ALL)) {

			throw new 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.");
		}

看一下ALL是什么

/** Wildcard representing <em>all</em> origins, methods, or headers. */
	public static final String ALL = "*";

所以如果使用2.4.0版本,还是设置*的话,访问API接口就会报错:

异常

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.
	at org.springframework.web.cors.CorsConfiguration.validateAllowCredentials(CorsConfiguration.java:457)
	at org.springframework.web.cors.CorsConfiguration.checkOrigin(CorsConfiguration.java:561)
	at org.springframework.web.cors.DefaultCorsProcessor.checkOrigin(DefaultCorsProcessor.java:174)
	at org.springframework.web.cors.DefaultCorsProcessor.handleInternal(DefaultCorsProcessor.java:116)
	at org.springframework.web.cors.DefaultCorsProcessor.processRequest(DefaultCorsProcessor.java:95)
	at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:87)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
	at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
	at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
	at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:358)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:271)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

修改方式

方式1

不使用CorsFilter,直接重写方法addCorsMappings

@Configuration
public class ResourcesConfig implements WebMvcConfigurer {
  /**
   * 跨域配置
   */
  @Override
  public void addCorsMappings(CorsRegistry registry) {
    //对那些请求路径进行跨域处理
    registry.addMapping("/**")
        // 允许的请求头,默认允许所有的请求头
        .allowedHeaders("*")
        // 允许的方法,默认允许GET、POST、HEAD
        .allowedMethods("*")
        // 探测请求有效时间,单位秒
        .maxAge(1800)
        // 支持的域
        .allowedOrigins("*");
  }
}

方式2

继续使用CorsFilter,使用官方推荐的allowedOriginPatterns
application.yml中新增配置:
(注:这里只是举个栗子…Origin的处理)

# 项目相关配置
project:
 uiPort: 8082
 basePath: http://localhost:${project.uiPort}
@Configuration
public class ResourcesConfig implements WebMvcConfigurer {
	@Value("${project.basePath}")
  private String basePath;

  @Bean
  public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    // 允许访问的客户端域名
    List<String> allowedOriginPatterns = new ArrayList<>();
    allowedOriginPatterns.add(basePath);
    config.setAllowedOriginPatterns(allowedOriginPatterns);
//    config.addAllowedOrigin(serverPort);
    // 允许服务端访问的客户端请求头
    config.addAllowedHeader("*");
    // 允许访问的方法名,GET POST等
    config.addAllowedMethod("*");
    // 对接口配置跨域设置
    source.registerCorsConfiguration("/**" , config);
    return new CorsFilter(source);
  }
}

到此这篇关于Springboot升级至2.4.0中出现的跨域问题分析及修改方案的文章就介绍到这了,更多相关Springboot2.4.0跨域内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 解决前后端分离 vue+springboot 跨域 session+cookie失效问题

    环境: 前端 vue ip地址:192.168.1.205 后端 springboot2.0 ip地址:192.168.1.217 主要开发后端. 问题: 首先登陆成功时将用户存在session中,后续请求在将用户从session中取出检查.后续请求取出的用户都为null. 解决过程: 首先发现sessionID不一致,导致每一次都是新的会话,当然不可能存在用户了.然后发现cookie浏览器不能自动保存,服务器响应set-cookie了 搜索问题,发现跨域,服务器响应的setCookie浏览器无

  • vue+springboot前后端分离实现单点登录跨域问题解决方法

    最近在做一个后台管理系统,前端是用时下火热的vue.js,后台是基于springboot的.因为后台系统没有登录功能,但是公司要求统一登录,登录认证统一使用.net项目组的认证系统.那就意味着做单点登录咯,至于不知道什么是单点登录的同学,建议去找一下万能的度娘. 刚接到这个需求的时候,老夫心里便不屑的认为:区区登录何足挂齿,但是,开发的过程狠狠的打了我一巴掌(火辣辣的一巴掌)...,所以这次必须得好好记录一下这次教训,以免以后再踩这样的坑. 我面临的第一个问题是跨域,浏览器控制台直接报CORS,

  • 浅谈SpringBoot2.4 配置文件加载机制大变化

    前言 Spring Boot 2.4.0.M2刚刚发布,它对 application.properties 和 application.yml 文件的加载方式进行重构.如果应用程序仅使用单个 application.properties 或 application.yml 作为配置文件,那么可能感受不到任何区别.但是如果您的应用程序使用更复杂的配置(例如,Spring Cloud 配置中心等),则需要来了解更改的内容以及原因. 为什么要进行这些更改 随着最新版本 Spring Boot 发布,S

  • 详解springboot设置cors跨域请求的两种方式

    1.第一种: public class CorsFilter extends OncePerRequestFilter { static final String ORIGIN = "Origin"; protected void doFilterInternal( HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOE

  • springboot+jsonp解决前端跨域问题小结

    现在咱们一起来讨论浏览器跨域请求数据的相关问题.说这样可能不是很标准,因为拒绝跨域请求数据并不是浏览器所独有的,之所以会出现跨域请求不了数据,是因为浏览器基本都实现了一个叫"同源策略"的安全规范.该规范具体是什么呢?我们在MDN上找到了一份资料,地址如下: 浏览器同源策略讲解 总的来说,当A网址和B网址在 协议 . 端口 . 域名 方面存在不同时,浏览器就会启动同源策略,拒绝A.B服务器之间进行数据请求. 说了同源策略,纸上得来终觉浅,绝知此事要躬行,到底同源策略是怎么体现的呢?下面我

  • vue+springboot实现项目的CORS跨域请求

    跨域资源共享CORS(Cross-origin Resource Sharing),是W3C的一个标准,允许浏览器向跨源的服务器发起XMLHttpRequest请求,克服ajax请求只能同源使用的限制.关于CORS的详细解读,可参考阮一峰大神的博客:跨域资源共享CORS详解.本文为通过一个小demo对该博客中分析内容的一些验证. 1.springboot+vue项目的构建和启动 细节不在此赘述,任何简单的springboot项目就可以,而前端vue项目只需用axios发ajax请求即可. 我的d

  • Springboot升级至2.4.0中出现的跨域问题分析及修改方案

    问题 Springboot升级至2.4.0中出现的跨域问题. 在Springboot 2.4.0版本之前使用的是2.3.5.RELEASE,对应的Spring版本为5.2.10.RELEASE. 升级至2.4.0后,对应的Spring版本为5.3.1. Springboot2.3.5.RELEASE时,我们可以使用CorsFilter设置跨域. 分析 版本2.3.5.RELEASE 设置跨域 设置代码如下: @Configuration public class ResourcesConfig

  • SpringBoot+Vue前后端分离实现请求api跨域问题

    前言 最近过年在家无聊,刚好有大把时间学习Vue,顺便做了一个增删查改+关键字匹配+分页的小dome,可是使用Vue请求后端提供的Api的时候确发现一个大问题,前后端分离了,但是请求的时候也就必定会有跨域这种问题,那如何解决呢? 前端解决方案 思路:由于Vue现在大多数项目但是用脚手架快速搭建的,所以我们可以直接在项目中创建一个vue.config.js的配置文件,然后在里面配置proxy代理来解决,话不多说,直接上代码 module.exports = { devServer: { proxy

  • 详解java 中Spring jsonp 跨域请求的实例

    详解java 中Spring jsonp 跨域请求的实例 jsonp介绍 JSONP(JSON with Padding)是JSON的一种"使用模式",可用于解决主流浏览器的跨域数据访问的问题.由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外.利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSO

  • 在vue项目中,使用axios跨域处理

    跨域,一个很是让人尴尬的问题,有些人可以在后台中设置请求头,但是很多前端并不具备后台的知识,并无法自己独立的搭建一个服务器,所以就变成了一个尴尬的事情 当然,有很多的虚拟服务器,能够解决跨域问题,他们的实质都是通过后台取与后台沟通,从而委婉的解决跨域问题正好,webpack正有这种功能,所以vue-cli也是有解决跨域的能力 当然,不可能我们直接发送ajax就成功,对吧,我们肯定要修改配置文件 代码: dev: { env: require('./dev.env'), port: 8080, a

  • vue中axios解决跨域问题和拦截器的使用方法

    vue中axios不支持vue.use()方式声明使用. 所以有两种方法可以解决这点: 第一种: 在main.js中引入axios,然后将其设置为vue原型链上的属性,这样在组件中就可以直接 this.axios使用了 import axios from 'axios'; Vue.prototype.axios=axios; components: this.axios({ url:"a.xxx", method:'post', data:{ id:3, name:'jack' } }

  • 详解Spring Boot 2.0.2+Ajax解决跨域请求的问题

    问题描述 后端域名为A.abc.com,前端域名为B.abc.com.浏览器在访问时,会出现跨域访问.浏览器对于javascript的同源策略的限制. HTTP请求时,请求本身会返回200,但是返回结果不会走success,并且会在浏览器console中提示: 已拦截跨源请求:同源策略禁止读取位于 https://www.baidu.com/ 的远程资源.(原因:CORS 头缺少 'Access-Control-Allow-Origin'). 解决方案 1.jsonp 2.引用A站的js 3.N

  • 在LayUI图片上传中,解决由跨域问题引起的请求接口错误的方法

    在LayUI图片上传中,解决由跨域问题引起的请求接口错误的方法 在ssm框架整合中,使用layui作为前端页面,拖拽图片上传,填写接口后,后台能够成功接收到数据,但由于页面资源和后台访问地址的不一致(即使域名一致但端口不一致)引起跨域问题,导致接收资源后在前端无法接收到后台返回的数据. 前台页面: <html> <head> <meta charset="UTF-8"> <title>校园网络打印</title> <li

  • Quarkus中filter过滤器跨域cors问题解决方案

    目录 前言 web依赖 过滤器filter开发 resteasy的filter vertx的filter Quarkus中的跨域 前言 Quarkus中的web模块是基于java标准web规范jax-rs构建的,实现则选用了jboss的resteasy.这部分只是请求路由转发部分实现.真正的请求接收则使用了eclipse开源的vert.x框架,底层也是基于netty的一个响应式开发框架.Quarkus将vert.x和resteasy集成在了一起,所以支持响应式和非响应式应用混合开发,这也是Qua

  • vue中前端代理跨域问题实例总结

    目录 前言 第一 第二 第三 代码 总结 前言 这几天在学习vue进行前后端交互时出现了跨域问题,也是经历查文章查文档和自己实践总结才最终解决.这篇文章就对此进行总结,以防忘记,同时也希望能对正在经历该问题困扰的同学们有所帮助.注意:这里讲解的是vue2.x版本的方法! 第一 首先我们需要先确定我们所使用的接口名,我这里使用的自己Java后端的接口和python后端的接口 http://localhost:8081/articles/findArticlePagehttp://127.0.0.1

  • 谈谈如何在ASP.NET Core中实现CORS跨域

    CORS(Cross-origin resource sharing)是一个W3C标准,翻译过来就是 "跨域资源共享",它主要是解决Ajax跨域限制的问题. CORS需要浏览器和服务器支持,现在所有现代浏览器都支持这一特性.注:IE10及以上 只要浏览器支持,其实CORS所有的配置都是在服务端进行的,而前端的操作浏览器会自动完成. 在本例中,将演示如何再ASP.NET Core中实现CORS跨域. 前期准备 你需要windows系统. 你需要安装IIS. 推荐使用VS2015 Upda

随机推荐