前端发送Fetch请求实现流式请求、模拟打字机效果等

  • 前端需要接收后端的流式返回数据,并实时渲染。
    普通的xhr请求都是等http协议数据包一次性返回之后才渲染,类似于ChatGPT的Http接口内容类型为text/event-stream。这种内容类型需要与浏览器建立持久连接并持续监听服务器返回的数据。

  • npm 方式安装类库

npm install @microsoft/fetch-event-source
  • 使用
let controller = new AbortController()
        const eventSource = fetchEventSource(fetchUrl, {
          method: 'POST',
          headers: {'Content-Type': 'application/json'},
          body: JSON.stringify(
              params
          ),
          signal: controller.signal,
          onopen() {
            console.log('open')
          },
          onmessage(event) {
            console.log('onMessage',event.data)
            let data = event.data
            let jsonData = JSON.parse(data);
          },
          onclose() {
            controller.abort();//出错后不要重试
            eventSource.close();
          },
          onerror(error) {
            console.log('close',error)
            controller.abort();//出错后不要重试
            eventSource.close();
          }

        })
      }

调用 fetchEventSource API可以返回一个对象,这个对象可以控制在连接失败时不要重试,直接关闭本次连接。

  1. onopen:建立连接的回调
  2. onmessage:接收一次数据段时回调,因为是流式返回,所以这个回调会被调用多次。
  3. onclose:正常结束的回调
  4. onerror:连接出现异常回调

onmessage的主要逻辑就是累加所有流式数据返回的内容,然后渲染到页面上,这里需要注意的是接口返回的为markdown格式的数据,所以还需要用到一个markdown转html的依赖库。

  • 光标闪烁效果模拟

这里其实是用了一个span来模拟实现的

 const cursorFlaskStr = "<span id='cursorFlask' style='opacity:1;font-weight: bold'>|</span>"
      setInterval(() => {
        let cursorFlask = document.getElementById("cursorFlask");
        if (cursorFlask) {
          let opacity = cursorFlask.style.opacity;
          if (opacity && opacity.trim() == '0') {
            cursorFlask.style.opacity = '1'
          } else {
            cursorFlask.style.opacity = '0'
          }
        }
      }, 245)

这里的逻辑是每次监听到后端的流式数据以后,动态拼接上已有的字符串,然后将markdown转为html格式,然后继续拼接上这个span标签一起渲染到页面上,这个时候再开启个定时器,定时器获取到这个标签,动态的调整这个标签的opcatity透明度就可以实现光标闪烁的效果了。

<think>好的,用户之前让我帮忙生成一个Vue3的AI聊天页面代码,现在他问的是如何对接深度求索(DeepSeek)的API。我需要先回顾之前的对话,确保这次回答能衔接上。 首先,用户已经有了一个基于Vue3的聊天页面,现在需要将模拟的AI回复换成真实的DeepSeek API。之前提供的代码里用了mockAIResponse函数,所以现在需要指导用户如何替换这个部分。 接下来,我得确认DeepSeek的API文档内容。通常,这类API需要API密钥,使用POST请求发送JSON数据,比如模型名称、消息数组等。可能需要构造正确的请求头,包括Authorization和Content-Type。 然后,用户可能需要安装axios或者使用fetch发送请求。之前的示例里用了mock,所以需要建议用户安装axios并替换掉模拟函数。 另外,错误处理很重要。之前的代码没有处理API调用可能出现的错误,所以需要补充try-catch块,捕获错误并给出提示,比如网络问题或权限问题。 还需要考虑异步处理和加载状态。在发送请求时,isLoading.value应该设置为true,请求完成后设为false,无论成功与否,所以要在finally块里处理。 另外,DeepSeek的API可能返回流式响应,但用户当前代码是等待完整响应。如果需要流式处理,可能需要调整代码,使用SSE或WebSocket,但考虑到用户当前是基础对接,可能先处理非流式的情况,后续再建议扩展。 安全方面,要提醒用户不要在前端暴露API密钥,建议通过后端服务中转,但可能用户只是测试,所以暂时先提供前端直接调用的方法,同时给出警告。 最后,样式和消息格式可能需要调整,比如消息内容可能是Markdown格式,可以建议用户添加相应的渲染支持,比如使用marked库。 总结步骤:替换mock函数为真实API调用,处理请求和响应,错误处理,安全提示,扩展建议。</think>以下是如何对接深度求索(DeepSeek)API的详细指南,基于Vue3项目的实现(接续之前提供的聊天页面代码): -- ### 一、前期准备 1. 注册DeepSeek账号并获取API Key - 访问[DeepSeek官网](https://www.deepseek.com/) - 创建账号后,在控制台获取API密钥(通常以`sk-`开头) 2. 安装必要依赖 ```bash npm install axios # 推荐使用axios进行HTTP请求 ``` -- ### 二、核心代码修改 #### 1. 替换mockAIResponse函数 ```javascript // 在<script setup>中替换原有mock函数 import axios from 'axios' const callDeepSeekAPI = async (userMessage) => { try { const response = await axios.post( 'https://api.deepseek.com/v1/chat/completions', { model: "deepseek-chat", // 根据实际模型调整 messages: [ { role: "system", content: "你是有帮助的AI助手" }, { role: "user", content: userMessage } ], temperature: 0.7 }, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${import.meta.env.VITE_DEEPSEEK_API_KEY}` } } ) return response.data.choices[0].message.content } catch (error) { console.error('API调用失败:', error) return "抱歉,暂时无法处理您的请求" } } ``` #### 2. 修改发送消息逻辑 ```javascript const sendMessage = async () => { // ...原有用户消息处理代码保持不变... try { isLoading.value = true // 替换原有的mock调用 const aiResponse = await callDeepSeekAPI(content) messages.push({ role: 'ai', content: aiResponse, timestamp: Date.now() }) } catch (error) { console.error('请求异常:', error) // 可以添加错误消息提示 messages.push({ role: 'ai', content: '请求处理失败,请稍后再试', timestamp: Date.now() }) } finally { isLoading.value = false scrollToBottom() } } ``` --- ### 三、环境变量配置 1. 创建`.env`文件 ```env VITE_DEEPSEEK_API_KEY=your_api_key_here ``` 2. 在vite.config.js中添加配置 ```javascript export default defineConfig({ // ...其他配置... server: { port: 3000 }, define: { 'import.meta.env': JSON.stringify(process.env) } }) ``` --- ### 四、安全增强建议 1. **不要在前端直接暴露API密钥**(当前方案仅适用于开发环境) - 推荐通过后端服务中转API请求 - 使用服务器端实现: ```javascript // 伪代码示例(Node.js端) app.post('/api/chat', async (req, res) => { const response = await axios.post('https://api.deepseek.com/v1/chat/completions', { // ...请求体... }, { headers: { Authorization: `Bearer ${process.env.DEEPSEEK_API_KEY}` } }) res.json(response.data) }) ``` --- ### 五、流式响应实现(可选) 如果需要实现打字机效果: ```javascript const callStreamingAPI = async (content) => { try { const response = await fetch('https://api.deepseek.com/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${import.meta.env.VITE_DEEPSEEK_API_KEY}` }, body: JSON.stringify({ model: "deepseek-chat", messages: [{ role: "user", content }], stream: true }) }) const reader = response.body.getReader() const decoder = new TextDecoder() let fullResponse = '' while (true) { const { done, value } = await reader.read() if (done) break const chunk = decoder.decode(value) const lines = chunk.split('\n') lines.forEach(line => { const message = line.replace(/^data: /, '') if (message === '[DONE]') return try { const parsed = JSON.parse(message) if (parsed.choices[0].delta.content) { fullResponse += parsed.choices[0].delta.content // 实时更新最后一条消息 messages[messages.length - 1].content = fullResponse } } catch (e) { console.log('解析错误:', e) } }) } } catch (error) { console.error('流式请求错误:', error) } } ``` -- ### 六、完整功能扩展建议 1. 添加以下功能提升体验: ```javascript // 在状态管理中增加 const errorMessage = ref(null) // 在API调用异常时显示错误提示 const showError = (message) => { errorMessage.value = message setTimeout(() => errorMessage.value = null, 5000) } // 在模板中添加错误提示组件 <div v-if="errorMessage" class="error-message"> {{ errorMessage }} </div> // 样式补充 .error-message { position: fixed; top: 20px; right: 20px; padding: 15px; background: #ff4444; color: white; border-radius: 8px; } ``` --- ### 七、注意事项 1. API调用成本管理 - 建议在服务端添加使用量监控 - 设置最大对话次数限制 2. 内容安全 - 建议在后端添加内容过滤 - 遵守DeepSeek的使用政策 3. 性能优化 - 添加消息缓存(localStorage) - 实现请求取消功能 - 添加请求重试机制 4. 用户体验优化 - 添加消息发送动画 - 实现消息编辑功能 - 添加消息加载状态指示器
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值