Eclipse中Extjs+Spring Boot同域不同端口CORS报错求助
CORS 问题根因与修复方案
你之前的配置完全不生效是写法错误导致的,和跨域规则本身无关,按以下步骤修改即可解决403与跨域拦截问题。
1. 现有配置的核心错误
- Tomcat
cors.allowed.origins配置缺少协议头:浏览器发起跨域请求时携带的Origin值是完整地址http://localhost:1841,你只配置localhost:1841会导致过滤器做源匹配时直接判定不通过。 - Tomcat 过滤器映射规则完全错误:
filter-mapping下的url-pattern是用来匹配后端自身接口路径的,你填前端地址localhost:1841会导致CorsFilter根本不会拦截后端接口请求,自然不会返回任何CORS相关响应头,这也是你改*通配源也不生效的核心原因。 - ExtJS 代理配置位置错误:
cors、withCredentials、useDefaultXhrHeader是AJAX请求的行为参数,不是请求头,你放在headers配置里不会生效,反而会被当成自定义请求头触发额外的预检校验。 - 缺少凭据支持配置:你前端开启了
withCredentials传递Cookie,但Tomcat CorsFilter默认不允许携带凭据的跨域请求,必须显式开启对应配置。
2. 正确配置步骤
修正Tomcat web.xml配置
<filter> <filter-name>CorsFilter</filter-name> <filter-class>org.apache.catalina.filters.CorsFilter</filter-class> <init-param> <param-name>cors.allowed.origins</param-name> <!-- 必须写带协议的完整源地址,开withCredentials不能用*通配 --> <param-value>http://localhost:1841</param-value> </init-param> <init-param> <param-name>cors.allowed.methods</param-name> <param-value>GET,POST,PUT,DELETE,HEAD,OPTIONS</param-value> </init-param> <init-param> <param-name>cors.allowed.headers</param-name> <param-value>Content-Type,X-Requested-With,Accept,Authorization,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value> </init-param> <init-param> <param-name>cors.exposed.headers</param-name> <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value> </init-param> <!-- 新增凭据支持配置 --> <init-param> <param-name>cors.support.credentials</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CorsFilter</filter-name> <!-- 匹配后端接口路径,不要填前端地址 --> <url-pattern>/MyBankingApp/*</url-pattern> </filter-mapping>
如果你用Spring Boot内嵌Tomcat运行,web.xml配置可能不被加载,更推荐直接用Spring Boot原生CORS配置,稳定性更高:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:1841") .allowedMethods("GET","POST","PUT","DELETE","HEAD","OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }
修正ExtJS Store配置
把跨域相关的行为参数从headers中移到proxy根层级:
Ext.define('MyBankingApp.store.User', { extend: 'Ext.data.Store', xtype: 'userStore', id:'userStoreID', requires: [ 'MyBankingApp.model.User' ], autoLoad: false, model: 'MyBankingApp.model.User', proxy: { type: 'ajax', url: 'http://localhost:8080/MyBankingApp/user', method: 'GET', // 跨域参数移到此处 cors: true, withCredentials: true, useDefaultXhrHeader: false, headers: { 'Content-Type': 'application/json' }, success: function (response) { alert(response); }, failure: function (response) { alert(response); } } });
改完重启后端服务,清空浏览器缓存再发请求即可正常访问。
前后端单端口部署方案
如果不想维护跨域配置,可以直接把前端静态资源和后端服务合并部署,从根源避免跨域问题:
- 前端执行
sencha app build命令,把编译生成的所有静态资源(html、js、css、静态资源文件)整体拷贝到Spring Boot项目的src/main/resources/static目录下。 - 把前端代码中所有接口请求的绝对路径改为相对路径,比如原来的
http://localhost:8080/MyBankingApp/user直接改成/MyBankingApp/user,不需要写域名和端口。 - 正常启动Spring Boot服务,默认使用8080端口,直接访问
http://localhost:8080/index.html即可打开前端页面,所有接口请求走同域同端口,完全不会触发CORS校验,开发和生产环境均可使用。
开发阶段如果不想每次修改前端都重新build,可以给Sencha watch配置转发规则,把/MyBankingApp开头的接口请求直接代理到8080端口的后端服务,前端开发依然用1841端口,同样不会产生跨域问题。
内容的提问来源于stack exchange,提问作者afraude
相关产品推荐
相关产品推荐

