使用JavaScript Fetch API向Java Spark发POST请求时Promise始终Pending
解决Fetch POST请求Promise一直Pending的CORS问题
兄弟,我之前也踩过这个一模一样的坑!你说的情况百分百是CORS配置没处理完整,尤其是Spark服务器没正确响应浏览器的OPTIONS预检请求,导致浏览器的跨域安全机制直接卡住了请求,才让Promise一直处于Pending状态。Postman不受浏览器同源策略限制,所以能正常拿到响应,但浏览器就不行。
下面给你一步步解决的方案:
1. 补全Spark服务器的CORS配置,重点处理OPTIONS请求
你只设置了Access-Control-Allow-Origin: *远远不够,因为带请求体的POST请求(比如你提交登录数据),浏览器会先发一个OPTIONS预检请求,询问服务器是否允许这个跨域请求。如果服务器没正确响应OPTIONS,浏览器就会直接拦截后续的POST请求,Promise自然就一直挂着了。
给你一套完整的Spark CORS配置代码:
// 先单独处理OPTIONS请求,返回200状态码和必要的响应头 options("/*", (req, res) -> { // 允许浏览器请求的所有头信息 String reqHeaders = req.headers("Access-Control-Request-Headers"); if (reqHeaders != null) { res.header("Access-Control-Allow-Headers", reqHeaders); } // 允许浏览器请求的方法 String reqMethod = req.headers("Access-Control-Request-Method"); if (reqMethod != null) { res.header("Access-Control-Allow-Methods", reqMethod); } return "OK"; }); // 全局设置CORS响应头 before((req, res) -> { res.header("Access-Control-Allow-Origin", "*"); // 如果你的登录请求需要携带Cookie(比如会话保持),注意这里不能用*,要改成你的Vue项目具体地址,比如http://localhost:8080 // res.header("Access-Control-Allow-Origin", "http://localhost:8080"); res.header("Access-Control-Allow-Credentials", "true"); // 只有当允许具体源时才能设为true res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With"); res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE"); });
这段代码的核心是:
- 单独处理OPTIONS请求,返回正确的响应头和200状态
- 全局设置允许的请求方法、请求头,确保浏览器能通过预检
2. 检查客户端Fetch的配置
确保你的Fetch请求设置了正确的Content-Type,因为登录数据一般是JSON格式,比如:
fetch('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: 'yourName', password: 'yourPwd' }) // 如果需要携带Cookie,加上下面这行,但注意服务器的Allow-Origin必须是具体地址,不能是* // credentials: 'include' }) .then(res => { // 先检查响应状态,避免解析失败 if (!res.ok) throw new Error('登录请求失败'); return res.json(); }) .then(data => console.log('登录结果:', data)) .catch(err => console.error('错误:', err));
这里要注意:如果你的Fetch用了credentials: 'include',服务器的Access-Control-Allow-Origin绝对不能是*,必须指定你的Vue项目的具体域名/地址,否则浏览器会拒绝接收响应,也会导致Promise pending。
3. 用浏览器开发者工具验证
打开浏览器的Network面板,刷新页面重新发起登录请求:
- 看是否有一个OPTIONS请求,状态码是不是200
- 检查OPTIONS请求的响应头里有没有
Access-Control-Allow-Headers、Access-Control-Allow-Methods这些字段 - 如果OPTIONS请求失败了,那问题肯定出在服务器的CORS配置上
只要把OPTIONS请求处理好,浏览器就会正常发送POST请求,Promise也就不会一直Pending了。
内容的提问来源于stack exchange,提问作者Razor
相关产品推荐
相关产品推荐

