普通数据
前端
发送:axios
接收:then里面些接收值
后端
发送:json
接收:request.json
流式数据
前端接收
先将字节码数据转成json 就是正常的
根据传过来的对象,看是否发送完毕
后端发送
stream
example
<template> <div> <a href="https://vitejs.dev" target="_blank"> <img alt="Vite logo" class="logo" src="/vite.svg"/> </a> <a href="https://vuejs.org/" target="_blank"> <img alt="Vue logo" class="logo vue" src="./assets/vue.svg"/> </a> </div> <div class="container"> <div class="module"> <h1>接收普通数据</h1> <input v-model="data"> <button @click="send">发送数据</button> <div v-if="response"> <h2>从后端接收到的数据:</h2> <p>{{ response }}</p> </div> </div> <div class="module"> <h1>接收流式数据</h1> <!-- <input v-model="streamdata">--> <button @click="StreamSend">接收</button> <div> <a v-for="(response, index) in streamResponse" :key="index"> {{ response }} <!-- 假设response是直接可显示的字符串或已经是处理过的格式 --> </a> </div> </div> </div> </template> <script setup> import {ref} from 'vue' import axios from 'axios' // 使用ref来响应式地存储流数据 const streamResponse = ref([]) // 将单个响应改为数组,以存储流中的每个数据点 const response = ref(null) const data = ref('') function send() { axios.post('http://127.0.0.1:8090/chat', { id: 1, name: data.value }).then( res => { console.log(res.data) response.value = res.data['message'] } ).catch( error => { console.error('请求错误', error) } ) } function StreamSend() { const url = 'http://127.0.0.1:8090/streamchat' const params = {message:"已发送"} // 使用fetch API发起POST请求 fetch(url, { method: 'POST', // 请求方法 headers: { 'Content-Type': 'application/json', // 请求头,指定内容类型为JSON }, body: JSON.stringify(params), // 将请求参数对象转换为JSON字符串 }).then(response => { const reader = response.body.getReader() // 获取响应体的读取器 const decoder = new TextDecoder('utf-8') //将字节流中的UTF-8编码字节转换成JavaScript字符串的方法//网络传输的数据通常是以字节流形式存在的,这些字节代表了文本的UTF-8编码形式。为了在JavaScript中处理这些文本数据(比如显示消息、解析JSON等),需要将其从字节转换为字符串 let sy = "" //异常处理的, // 逐块处理响应流,将字节码数据解码出来。 result是reader.read function ReadableStream(result) { let line = decoder.decode(result.value, {stream: !result.done}) //result.value 是字节码 解码当前块,并根据结果是否完整来决定是否停止流式传输/line=data: 2 // 将新解码的数据与之前可能残留的数据拼接 line = sy + line console.log('line',line) sy = "" // 清空拼接缓存 // 特殊处理:如果数据包含"ping",则过滤掉这部分 。。为什么会包含ping if (line.includes("ping")) { const errs = line.split('\n') let raw = [] errs.forEach(e => { if (!e.includes("ping") && e.startsWith("data")) { raw.push(e) } }) // 重新组合过滤后的数据 line = raw.join("\n") } // 以'data:'作为分隔符分割数据,每个部分代表一个独立的消息 ['', ' 9\n\n'] const lines = line.split('data:') console.log('aaaa',lines) lines.forEach(e => { //拿到解码后的值 console.log('e',e) if (!e) return // 如果分割后的某部分为空,则跳过 let value; try { value = JSON.parse(e)// 尝试解析为JSON对象 streamResponse.value.push(value) console.log('解码后',value) } catch (err) { // 如果JSON.parse(e)抛出错误,这通常意味着e不是一个有效的JSON字符串。这种情况下,假设错误是因为数据被不幸地分割到了两个块中,所以把当前字符串e赋值给sy sy = e return } console.log('sss',value)// 此处可以添加处理逻辑,例如合并相同uuid的消息等 }) // 如果读取操作没有完成(result.done为false),ReadableStream函数将再次调用reader.read().then(ReadableStream),继续读取下一个数据块。 if (!result.done) { return reader.read().then(ReadableStream) } } return reader.read().then(ReadableStream) } ) } </script> <style> .container { display: flex; /* 使用 Flexbox 布局 */ } .module { flex: 1; /* 设置模块的弹性,使其平均占据可用空间 */ margin-right: 130px; /* 可选:增加模块之间的间距 */ margin-left: 130px; /* 可选:增加模块之间的间距 */ } </style>
from flask import Flask, request, jsonify, Response from flask_cors import CORS import requests import json import pandas as pd import re import time app = Flask(__name__) CORS(app) @app.route('/chat', methods=['POST']) def submit_data(): # 从前端请求中获取数据 data_from_frontend = request.json print(data_from_frontend['name']) # 假设进行了一些处理后,要返回给前端的数据 processed_data = {'status': 'success', 'message': '前端发送的 {} 我已成功接收'.format(data_from_frontend['name'])} # 将处理后的数据返回给前端 return jsonify(processed_data) def generate_stream(): # 这里是你的数据生成逻辑 # 作为示例,我们每秒发送一个数字 for number in range(10): # 假设我们发送10次数据 yield f"data: {number}\n\n" # 注意格式:data: <数据>\n\n time.sleep(1) # 模拟数据生成延迟 @app.route('/streamchat', methods=['POST']) def stream_chat(): print(request.json) data_stream = request.json['message'] if data_stream =='已发送': # 创建一个生成器作为响应体,content_type 设置为 text/event-stream return Response(generate_stream(), content_type='text/event-stream') if __name__ == '__main__': app.run(port=8090)