chatGPT前端流式輸出js實(shí)現(xiàn)三種方法—fetch、SSE、websocket
項(xiàng)目需要接入chatgpt提供的api,后端返回流式的字符,前端接收并實(shí)時(shí)顯示。在JavaScript中,使用Stream流通常指的是處理數(shù)據(jù)流的一種方式。Stream可以是可讀的、可寫的、或者既可讀又可寫的。它們允許數(shù)據(jù)被處理成塊,而不是一次性處理整個(gè)數(shù)據(jù)集,這對于處理大量數(shù)據(jù)或者來自網(wǎng)絡(luò)請求的數(shù)據(jù)非常有用。
一、fetch實(shí)現(xiàn)stream
fetch 本身不直接支持流式輸出,但你可以使用 ReadableStream 和 TextDecoder 等 Web Streams API 來實(shí)現(xiàn)類似的效果。
function streamOutput(msg) {
// 發(fā)送 POST 請求
fetch('url', {
method:"POST",
body:JSON.stringify({ "content": msg}),
timeout: 0,
dataType:"text/event-stream",
headers:{
"Content-Type":"application/json"
},
}).then(response => {
// 檢查響應(yīng)是否成功
if (!response.ok) {
throw new Error('Network response was not ok');
}
// 返回一個(gè)可讀流
return response.body;
}).then(body => {
disableLoading();
const reader = body.getReader();
// 讀取數(shù)據(jù)流
function read() {
return reader.read().then(({ done, value }) => {
// 檢查是否讀取完畢
if (done) {
console.log('已傳輸完畢');
return;
}
// 處理每個(gè)數(shù)據(jù)塊
console.log('收到的數(shù)據(jù):', value);
// 繼續(xù)讀取下一個(gè)數(shù)據(jù)塊
read();
});
}
// 開始讀取數(shù)據(jù)流
read();
}).catch(error => {console.error('Fetch error:', error);});
}二、SSE實(shí)現(xiàn)(只支持GET請求)
在 SSE 中,瀏覽器通過發(fā)送 HTTP GET 請求到服務(wù)器上特定的 SSE 端點(diǎn)(endpoint),然后服務(wù)器通過該連接發(fā)送事件(event)和相關(guān)數(shù)據(jù)到客戶端,故SSE 主要使用 GET 請求。EventSource不支持發(fā)送請求頭,如果需要發(fā)送請求頭則要用EventSourcePolyfill。
在使用EventSourcePolyfill前需要引入 Server-Sent Events (SSE) 的 JavaScript 庫。
引入方式一:npm或yarn
npm install event-source-polyfill
yarn add event-source-polyfill
在js文件中引入
import EventSource from 'event-source-polyfill';
引入方式二:eventsource
下載倉庫:https://github.com/Yaffle/EventSource
注意:進(jìn)入src文件下載所需eventsource.js或eventsource.min.js文件,引入時(shí)注意路徑,如果是jsp文件用絕對路徑
<script type="text/javascript" src="/path/eventsource.js"></script>
function streamOutput() {
// 創(chuàng)建 EventSourcePolyfill連接,如果不需要發(fā)送請求頭可以使用EventSource即可
const eventSource = new EventSourcePolyfill('url',{
headers:{
"Content-Type":"application/json"
}
});
// 處理 SSE 消息
eventSource.onmessage = function (event) {
console.log('接收SSE的消息:', event.data);
// 在這里處理接收到的流式數(shù)據(jù)
};
// 處理 SSE 連接打開事件
eventSource.onopen = function (event) {
console.log('SSE連接完成:', event);
};
// 處理 SSE 連接關(guān)閉事件
eventSource.onclose = function (event) {
console.log('SSE連接關(guān)閉:', event);
};
// 處理 SSE 錯(cuò)誤事件
eventSource.onerror = function (error) {
console.error('SSE EventSource error:', error);
};
}三、websocket實(shí)現(xiàn)(url必須為ws或wss開頭的接口)
WebSocket 是一種全雙工通信協(xié)議,允許客戶端和服務(wù)器之間進(jìn)行實(shí)時(shí)的雙向通信,并且支持POST請求。但是值得注意的是WebSocket只支持ws或wss開頭的接口。WebSocket 握手時(shí)并沒有提供直接設(shè)置請求頭的標(biāo)準(zhǔn)方法,它的握手階段是由瀏覽器自動(dòng)處理的,因此你不能直接在創(chuàng)建 WebSocket 連接時(shí)設(shè)置請求頭,但可以通過通過 URL 參數(shù)傳遞的方式傳遞信息。
function streamOutput(msg) {
const socket = new WebSocket('url');
// 連接打開時(shí)觸發(fā)
socket.addEventListener('open', event => {
console.log('WebSocket連接完成:', event);
// 處理接收到的消息
socket.addEventListener('message', event => {
console.log('接收消息:', event.data);
// 在這里處理接收到的流式數(shù)據(jù)
});
});
// 連接關(guān)閉時(shí)觸發(fā)
socket.addEventListener('close', event => {
console.log('WebSocket連接關(guān)閉:', event);
});
// 處理錯(cuò)誤時(shí)觸發(fā)
socket.addEventListener('error', error => {
console.error('WebSocket error:', error);
});
}四、總結(jié)
- Python使用WebSocket和SSE實(shí)現(xiàn)HTTP服務(wù)器消息推送方式
- Websocket的用法及常見應(yīng)用場景
- SpringBoot實(shí)現(xiàn)SSE(Server-Sent?Events)的完整指南
- Springboot?實(shí)現(xiàn)Server-Sent?Events的項(xiàng)目實(shí)踐
- Spring Boot中使用Server-Sent Events (SSE) 實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)推送教程
- C#實(shí)現(xiàn)SSE(Server-Sent Events)服務(wù)端和客戶端的示例代碼
- Spring Boot中使用SSE(Server-Sent Events)實(shí)現(xiàn)聊天功能:替代websocket服務(wù)器推送
相關(guān)文章
JavaScript實(shí)現(xiàn)簡單購物小表格
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)簡單購物小表格,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
Next.js預(yù)期錯(cuò)誤與未捕獲異常的處理方法
在開發(fā)過程中,錯(cuò)誤是不可避免的,如何優(yōu)雅地處理這些錯(cuò)誤是提升應(yīng)用穩(wěn)定性與用戶體驗(yàn)的關(guān)鍵,本文將詳細(xì)介紹如何在 Next.js 中處理預(yù)期錯(cuò)誤與未捕獲的異常,包括使用 useFormState 處理預(yù)期錯(cuò)誤,使用錯(cuò)誤邊界捕獲未捕獲的異常,需要的朋友可以參考下2025-03-03

