uni-app 【报Bug】plus.net.XMLHttpRequest onreadystatechange 安卓端监听不到流式输出

发布于 1周前 作者 yibo5220 来自 Uni-App

uni-app 【报Bug】plus.net.XMLHttpRequest onreadystatechange 安卓端监听不到流式输出

类别 信息
产品分类 uniapp/App
PC开发环境 Windows
PC操作系统版本 11
HBuilderX类型 正式
HBuilderX版本 3.8.7
手机系统 Android
手机系统版本 Android 13
手机厂商 小米
手机机型 redmi note 11
页面类型 vue
vue版本 vue2
打包方式 云端
项目创建方式 HBuilderX

示例代码:

// 在页面中创建 XMLHttpRequest 对象
let xhr = new plus.net.XMLHttpRequest()

//const msgNum = messageList.value.length;    
xhr.onreadystatechange = function() {    
    console.log("onreadystatechange: " + xhr.readyState);    
    if (xhr.readyState == 3) {    
        // 这里安卓端只执行一次,ios端正常    
        // 处理 HTTP 数据块    
        //let result=JSON.parse(xhr.responseText)    
        that.parseContent(xhr.responseText)    
        //console.log(xhr)    
    }    
    if (xhr.readyState == 4) {    
        console.log("问答完毕")    
        that.loadding = false    
        that.messageList.push({    
            content: that.messages[that.messages.length - 1].content,    
            role: "assistant"    
        })    
        uni.setStorageSync("chatgpt_messages", that.messages)    
        uni.setStorageSync("chatgpt_messageList", that.messageList)    
    }    
}    

xhr.onload = function() {    
    console.log("onreadystatechange: " + xhr.readyState);    
}    

xhr.open("POST", "https://111.com/completions", true)    

xhr.setRequestHeader("Content-type", "application/json");    
//xhr.responseType = "document"    
//xhr.timeout = 0    

xhr.send(JSON.stringify({    
    model: "gpt-3.5-turbo",    
    stream: true,    
    messages: messageList,    
}))

操作步骤:

xhr.readyState == 3 不执行,响应结果最后一次性输出

预期结果:

xhr.readyState == 3 不执行,响应结果最后一次性输出

实际结果:

xhr.readyState == 3 不执行,响应结果最后一次性输出

bug描述:

onreadystatechange 安卓端监听不到流式输出


3 回复

请问找到安卓端流式输出的方法了没


改成webview了

uni-app 中使用 plus.net.XMLHttpRequest 进行网络请求时,可能会遇到在安卓端无法监听流式输出的问题。这个问题通常与安卓端的底层实现或 XMLHttpRequest 的行为有关。以下是一些可能的原因和解决方案:

1. 使用 onprogress 事件

XMLHttpRequest 提供了 onprogress 事件,可以用来监听流式输出的进度。尝试使用 onprogress 事件来替代 onreadystatechange

let xhr = new plus.net.XMLHttpRequest();
xhr.open('GET', 'https://example.com/stream', true);

xhr.onprogress = function (event) {
    if (xhr.readyState === 3) { // 3 表示正在接收数据
        let chunk = xhr.responseText;
        console.log('Received chunk:', chunk);
    }
};

xhr.onreadystatechange = function () {
    if (xhr.readyState === 4) { // 4 表示请求完成
        console.log('Request completed:', xhr.responseText);
    }
};

xhr.send();

2. 使用 fetch API

如果你可以接受使用 fetch API,fetch 提供了更好的流式处理支持。你可以使用 fetch 来替代 XMLHttpRequest

fetch('https://example.com/stream')
    .then(response => {
        const reader = response.body.getReader();
        function pump() {
            return reader.read().then(({ done, value }) => {
                if (done) {
                    console.log('Stream complete');
                    return;
                }
                console.log('Received chunk:', new TextDecoder().decode(value));
                return pump();
            });
        }
        return pump();
    })
    .catch(error => {
        console.error('Fetch error:', error);
    });

3. 检查安卓端的限制

安卓端可能对 XMLHttpRequest 的行为有一些限制,尤其是在处理流式数据时。确保你的安卓版本和 uni-app 版本是最新的,以避免已知的 bug。

4. 使用 WebSocket

如果你需要实时流式数据传输,考虑使用 WebSocketWebSocket 提供了双向通信的能力,并且非常适合实时数据传输。

let ws = new WebSocket('wss://example.com/ws');

ws.onmessage = function (event) {
    console.log('Received message:', event.data);
};

ws.onopen = function () {
    console.log('WebSocket connection opened');
};

ws.onclose = function () {
    console.log('WebSocket connection closed');
};

ws.onerror = function (error) {
    console.error('WebSocket error:', error);
};

5. 调试和日志

增加调试信息,确保你能够准确地看到请求的状态和响应。通过日志可以帮助你更好地理解问题的根源。

let xhr = new plus.net.XMLHttpRequest();
xhr.open('GET', 'https://example.com/stream', true);

xhr.onreadystatechange = function () {
    console.log('ReadyState:', xhr.readyState);
    if (xhr.readyState === 3) {
        console.log('Partial response:', xhr.responseText);
    }
    if (xhr.readyState === 4) {
        console.log('Full response:', xhr.responseText);
    }
};

xhr.send();

6. 检查服务器端

确保服务器端支持流式输出,并且没有在发送数据时进行缓冲或延迟。

7. 使用 uni.request

如果 plus.net.XMLHttpRequest 在安卓端存在问题,可以尝试使用 uni.request,它是 uni-app 封装的网络请求方法,可能对跨平台兼容性更好。

uni.request({
    url: 'https://example.com/stream',
    method: 'GET',
    success: function (res) {
        console.log('Response:', res.data);
    },
    fail: function (error) {
        console.error('Request failed:', error);
    }
});
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!