chatGPT前端流式輸出js實(shí)現(xiàn)三種方法—fetch、SSE、websocket
項(xiàng)目需要接入chatgpt提供的api,后端返回流式的字符,前端接收并實(shí)時(shí)顯示。在JavaScript中,使用Stream流通常指的是處理數(shù)據(jù)流的一種方式。Stream可以是可讀的、可寫的、或者既可讀又可寫的。它們?cè)试S數(shù)據(jù)被處理成塊,而不是一次性處理整個(gè)數(shù)據(jù)集,這對(duì)于處理大量數(shù)據(jù)或者來(lái)自網(wǎng)絡(luò)請(qǐng)求的數(shù)據(jù)非常有用。
一、fetch實(shí)現(xiàn)stream
fetch 本身不直接支持流式輸出,但你可以使用 ReadableStream 和 TextDecoder 等 Web Streams API 來(lái)實(shí)現(xiàn)類似的效果。
function streamOutput(msg) {
// 發(fā)送 POST 請(qǐng)求
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();
});
}
// 開(kāi)始讀取數(shù)據(jù)流
read();
}).catch(error => {console.error('Fetch error:', error);});
}二、SSE實(shí)現(xiàn)(只支持GET請(qǐng)求)
在 SSE 中,瀏覽器通過(guò)發(fā)送 HTTP GET 請(qǐng)求到服務(wù)器上特定的 SSE 端點(diǎn)(endpoint),然后服務(wù)器通過(guò)該連接發(fā)送事件(event)和相關(guān)數(shù)據(jù)到客戶端,故SSE 主要使用 GET 請(qǐng)求。EventSource不支持發(fā)送請(qǐng)求頭,如果需要發(fā)送請(qǐng)求頭則要用EventSourcePolyfill。
在使用EventSourcePolyfill前需要引入 Server-Sent Events (SSE) 的 JavaScript 庫(kù)。
引入方式一:npm或yarn
npm install event-source-polyfill
yarn add event-source-polyfill
在js文件中引入
import EventSource from 'event-source-polyfill';
引入方式二:eventsource
下載倉(cāng)庫(kù):https://github.com/Yaffle/EventSource
注意:進(jìn)入src文件下載所需eventsource.js或eventsource.min.js文件,引入時(shí)注意路徑,如果是jsp文件用絕對(duì)路徑
<script type="text/javascript" src="/path/eventsource.js"></script>
function streamOutput() {
// 創(chuàng)建 EventSourcePolyfill連接,如果不需要發(fā)送請(qǐng)求頭可以使用EventSource即可
const eventSource = new EventSourcePolyfill('url',{
headers:{
"Content-Type":"application/json"
}
});
// 處理 SSE 消息
eventSource.onmessage = function (event) {
console.log('接收SSE的消息:', event.data);
// 在這里處理接收到的流式數(shù)據(jù)
};
// 處理 SSE 連接打開(kāi)事件
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開(kāi)頭的接口)
WebSocket 是一種全雙工通信協(xié)議,允許客戶端和服務(wù)器之間進(jìn)行實(shí)時(shí)的雙向通信,并且支持POST請(qǐng)求。但是值得注意的是WebSocket只支持ws或wss開(kāi)頭的接口。WebSocket 握手時(shí)并沒(méi)有提供直接設(shè)置請(qǐng)求頭的標(biāo)準(zhǔn)方法,它的握手階段是由瀏覽器自動(dòng)處理的,因此你不能直接在創(chuàng)建 WebSocket 連接時(shí)設(shè)置請(qǐng)求頭,但可以通過(guò)通過(guò) URL 參數(shù)傳遞的方式傳遞信息。
function streamOutput(msg) {
const socket = new WebSocket('url');
// 連接打開(kāi)時(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é)
相關(guān)文章
javascript游戲開(kāi)發(fā)之《三國(guó)志曹操傳》零部件開(kāi)發(fā)(三)情景對(duì)話中仿打字機(jī)輸出文字
前兩講我告訴了大家如何使人物移動(dòng),那么今天我們就來(lái)看看如何實(shí)現(xiàn)仿《三國(guó)志曹操傳》人物情景對(duì)話,感興趣的朋友可以了解下,希望本文對(duì)你有所幫助2013-01-01
fckeditor部署到weblogic出現(xiàn)xml無(wú)法讀取及樣式不能顯示問(wèn)題的解決方法
這篇文章主要介紹了fckeditor部署到weblogic出現(xiàn)xml無(wú)法讀取及樣式不能顯示問(wèn)題的解決方法,分析了問(wèn)題出現(xiàn)的原因及相關(guān)配置文件設(shè)置技巧,需要的朋友可以參考下2017-03-03
使用json-server簡(jiǎn)單完成CRUD模擬后臺(tái)數(shù)據(jù)的方法
這篇文章主要介紹了使用json-server簡(jiǎn)單完成CRUD模擬后臺(tái)數(shù)據(jù)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
JS實(shí)現(xiàn)多重選項(xiàng)卡切換輪播圖
canvas實(shí)現(xiàn)動(dòng)態(tài)小球重疊效果

