You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:49:38