如何解决ExtJS Store的CORS跨域问题(要求使用Ext.Store而非Ext.Ajax)
问题背景
我需要使用Ext.Store而非Ext.Ajax获取数据,当前的Store代码如下:
Ext.define('Vidly.store.Customers', { extend: 'Ext.data.Store', alias: 'store.customers', storeId: 'customers', model: 'Vidly.model.Customer', autoLoad: true, proxy: { type: 'ajax', headers : { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, DELETE, PUT', 'Access-Control-Allow-Headers': 'x-requested-with, Content-Type, origin, authorization, accept, client-security-token' }, api : { read : 'https://localhost:44378/api/Customers' }, reader: { type: 'json', } } });
但我持续遇到以下CORS错误:
XMLHttpRequest at 'https://localhost:44378/api/Customers?_dc=1612003742512&page=1&start=0&limit=25' from origin 'http://localhost:1967' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我不确定该调整API端还是SPA端配置,已经移除了SPA端所有CORS相关代码,且该API在其他SPA中可以正常工作。我的.NET 5 API的Startup配置如下:
ConfigureServices方法中添加了services.AddCors();Configure方法中添加了app.UseCors(options => options.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
问题分析与解决方案
1. 移除前端不必要的CORS请求头
你在ExtJS Store的proxy中添加的Access-Control-*请求头是错误的——这类头是由API服务器返回给浏览器的,而非前端请求发送的。前端主动发送这些头反而会干扰浏览器的预请求(OPTIONS)处理,这很可能是当前报错的核心原因。
修改后的Store代码:
Ext.define('Vidly.store.Customers', { extend: 'Ext.data.Store', alias: 'store.customers', storeId: 'customers', model: 'Vidly.model.Customer', autoLoad: true, proxy: { type: 'ajax', api : { read : 'https://localhost:44378/api/Customers' }, reader: { type: 'json', } } });
2. 确认.NET 5 API的CORS中间件顺序
在.NET 5中,中间件的执行顺序直接影响功能生效与否,UseCors必须放在正确的位置:
- 位于
UseRouting之后,UseAuthorization和UseEndpoints之前
正确的Configure方法示例:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); // 路由中间件 app.UseRouting(); // CORS中间件必须放置在此处 app.UseCors(options => options.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
如果UseCors放在UseAuthorization之后,API将无法为预请求添加正确的CORS响应头,导致跨域校验失败。
3. 验证API预请求响应
可以通过浏览器开发者工具(Network面板)或Postman查看OPTIONS预请求的响应头,确认是否包含Access-Control-Allow-Origin: *(或你的前端域名)。如果响应中没有该头,说明API的CORS配置仍存在问题。
结合你提到的“API在其他SPA中正常工作”的情况,大概率是前端请求头干扰或API中间件顺序的小问题,按照上述步骤调整后即可解决。
内容的提问来源于stack exchange,提问作者Samuel Marvin Aguilos

