前端实现 post 接口请求 SSE

47 阅读1分钟

实现思路

使用 fetch 发送请求,然后将返回的可读流转成字符串


function explainText(text: string, tokenLimit: number, tabId: number) {
  if (tokenLimit <= 0) {
    alert('token not enough')
  }
  const apiUrl = 'https://www.example.com/api/gpt/chat';
  const payload = {
    messages: [{ role: 'user', content: text }]
  };

  fetch(apiUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'text/event-stream'
    },
    body: JSON.stringify(payload)
  })
  .then(response => {
    const reader = response?.body?.getReader();
    const decoder = new TextDecoder();
    let translatedText = '';

    function read() {
      reader?.read().then(({ done, value }) => {
        if (done) {
          return;
        }
        const chunk = decoder.decode(value, { stream: true });
        const lines = chunk.split('\n\n');
        lines.forEach(line => {
          if (line.startsWith('data: ')) {
            try {
              const withoutDataAhead = line.substring(6);
              if (withoutDataAhead === '[DONE]') {
                console.log('success and done');
                return;
              }
              if (withoutDataAhead === '[ERROR]') {
                console.error(`AI 接口错误 ${line}`);
                return;
              }

              const data = JSON.parse(line.substring(6));
              const {c: content = '', usage  } = data;
              if (usage) {
                console.log('usage', usage);
              }
              translatedText += content;
              chrome.tabs.sendMessage(tabId, { type: 'AI_TEXT', payload: { translatedText } });
            } catch (e) {
              console.error('JSON 解析错误:', e);
            }
          }
        });

        read();
      });
    }

    read();
    console.log('translatedText', translatedText);
  })
  .catch(error => console.error('Error:', error));
}