向Tomcat9 Web服务发送Basic Auth的Ajax跨域请求问题
跨域调用Spring Web服务的配置与排查指南
针对你用jQuery/Ajax跨域调用Java/Spring Web服务的场景,结合你提供的代码和Tomcat CORS配置的信息,我整理了以下关键要点来解决可能遇到的问题:
1. 补全并验证Tomcat CORS过滤器配置
你提到已经配置了Tomcat的CORS过滤器,但配置内容不完整。以下是符合你场景的完整配置,需要确保覆盖所有必要参数:
<filter> <filter-name>CorsFilter</filter-name> <filter-class>org.apache.catalina.filters.CorsFilter</filter-class> <!-- 允许的前端源,替换为你的实际域名,多个用逗号分隔 --> <init-param> <param-name>cors.allowed.origins</param-name> <param-value>http://domainOfAjaxCall</param-value> </init-param> <!-- 必须包含OPTIONS方法,跨域预请求会用到 --> <init-param> <param-name>cors.allowed.methods</param-name> <param-value>GET,POST,PUT,DELETE,OPTIONS</param-value> </init-param> <!-- 允许Basic Auth所需的Authorization头,以及Content-Type等常用头 --> <init-param> <param-name>cors.allowed.headers</param-name> <param-value>Content-Type,Authorization</param-value> </init-param> <!-- 开启凭证支持,和Ajax的withCredentials:true对应 --> <init-param> <param-name>cors.support.credentials</param-name> <param-value>true</param-value> </init-param> <!-- 暴露必要的响应头给前端 --> <init-param> <param-name>cors.exposed.headers</param-name> <param-value>Access-Control-Allow-Origin</param-value> </init-param> </filter> <filter-mapping> <filter-name>CorsFilter</filter-name> <url-pattern>/*</url-pattern> <!-- 确保覆盖你的API路径 --> </filter-mapping>
关键注意点:
cors.support.credentials必须设为true,否则浏览器会阻止携带Cookie或HTTP凭证的跨域请求- 不要遗漏
OPTIONS方法,跨域请求发起前浏览器会自动发送OPTIONS预请求验证权限
2. 优化Ajax请求的Basic Auth处理
你当前的Ajax代码使用了username和password参数,jQuery会自动生成Authorization头,但在跨域场景下需要确保这个头被CORS过滤器允许(已在上面配置中包含)。如果遇到权限问题,可以手动构造Authorization头来测试:
// 编码Basic Auth凭证,注意处理特殊字符的编码问题 var authToken = btoa("basicUsername:basicPassword"); var request = $.ajax({ xhrFields: { withCredentials: true }, method: "GET", url: "http://<ipOfWebService>/api/myEndPoint/4313991?country=UK", dataType: "xml", crossDomain: true, headers: { "Authorization": "Basic " + authToken } })
3. 避免Spring与Tomcat CORS配置冲突
如果你的Spring应用同时使用了@CrossOrigin注解或全局CORS配置,可能会和Tomcat的CORS过滤器产生冲突。建议统一使用一种配置方式:
- 若坚持用Tomcat过滤器,移除Spring端所有CORS相关注解和配置
- 若使用Spring全局配置,可以参考以下代码:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("http://domainOfAjaxCall") .allowedMethods("GET", "OPTIONS") .allowedHeaders("Content-Type", "Authorization") .allowCredentials(true) .maxAge(3600); // 缓存预请求结果,减少OPTIONS请求次数 } }
4. 浏览器端调试技巧
打开浏览器开发者工具(F12),切换到Network标签:
- 检查是否有OPTIONS预请求,确认其响应状态码为200
- 查看实际GET请求的响应头,确认存在
Access-Control-Allow-Origin: http://domainOfAjaxCall和Access-Control-Allow-Credentials: true - 若有错误,查看Console面板的跨域错误提示,根据提示针对性调整配置
内容的提问来源于stack exchange,提问作者shiny76
相关产品推荐
相关产品推荐

