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

使用JavaScript的fetch发送Partial/Ajax请求仅获部分响应的问题

问题描述

我用JavaScript的fetch发起POST请求,目标服务器返回XML格式的partial-response,但响应是分块返回的,fetch只能拿到第一部分内容。试过await、then等异步处理方式,结果还是一样。

我的请求代码:

let response = await fetch(url, {
        method: 'POST',
        body: // 请求体内容
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
            'Connection': 'close',
            'Faces-Request': 'partial/ajax',
            'X-Requested-With': 'XMLHttpRequest',
            'Accept': 'application/xml, text/xml, */*; q=0.01',
            'Accept': '*/*',
            'Accept-Encoding': 'gzip, deflate',
            // 其他Cookie、User-Agent等头信息
        }});

尝试过XMLHttpRequest,但误以为需要手动设置Cookie头(受浏览器安全限制无法直接设置),所以没成功使用。

期望的完整响应:

<?xml version='1.0' encoding='UTF-8'?>
<partial-response id="j_id1">
    <changes>
        <update id="form:messages">
            <![CDATA[_]]></update>
        <update id="form:j_idt117">
            <![CDATA[_]]></update>
        <update id="form:j_idt133">
            <![CDATA[_]]></update>
        <update id="form:j_idt228">
            <![CDATA[_]]></update>
        <update id="j_id1:javax.faces.ViewState:0"><![CDATA[_]]></update>
    </changes>
</partial-response>

实际获取到的响应:

<?xml version='1.0' encoding='UTF-8'?>
<partial-response id="j_id1">
    <changes>
        <update id="form:j_idt228">
            <![CDATA[_]]></update>
        <update id="j_id1:javax.faces.ViewState:0"><![CDATA[_]]></update>
    </changes>
</partial-response>

想知道fetch有没有机制能获取完整的分块响应,曾考虑等待响应完全返回后再读取,但没找到相关文档。

解决方案

1. 移除Connection: close头

你设置的Connection: close会强制服务器发送部分数据后关闭连接,导致fetch无法接收后续分块内容。浏览器默认使用keep-alive连接,移除这个头即可让服务器完整发送所有分块:

headers: {
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
    // 移除 'Connection': 'close'
    'Faces-Request': 'partial/ajax',
    'X-Requested-With': 'XMLHttpRequest',
    'Accept': 'application/xml, text/xml, */*; q=0.01',
    // 重复的Accept头会被浏览器忽略,保留一个合适的即可
    'Accept-Encoding': 'gzip, deflate',
    // 其他Cookie、User-Agent等头信息
}

2. 正确读取完整响应体

fetch会自动等待所有分块接收完成后返回response对象,你需要通过response.text()或response.xml()(部分浏览器支持)读取完整内容:

let response = await fetch(url, { /* 调整后的配置 */ });
// 读取完整响应文本
let fullXmlText = await response.text();
// 解析为XML文档
let parser = new DOMParser();
let xmlDoc = parser.parseFromString(fullXmlText, "application/xml");
// 后续操作xmlDoc即可获取完整的partial-response

3. 关于XMLHttpRequest的Cookie问题

XMLHttpRequest不需要手动设置Cookie头,浏览器会自动携带当前域名下的Cookie(同源请求默认支持)。如果是跨域请求,只需开启withCredentials即可:

let xhr = new XMLHttpRequest();
xhr.open('POST', url);
xhr.withCredentials = true; // 跨域时允许携带Cookie
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
xhr.setRequestHeader('Faces-Request', 'partial/ajax');
// 其他必要头设置
xhr.onload = function() {
    if (xhr.status === 200) {
        let xmlDoc = xhr.responseXML;
        // 处理完整响应内容
    }
};
xhr.send(body);

4. 验证服务器传输编码

检查服务器响应头是否包含Transfer-Encoding: chunked,如果是,只要连接保持打开(移除Connection: close),fetch会自动拼接所有分块内容。

内容的提问来源于stack exchange,提问作者Nicolas B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 09:35:18