普通数据
前端
发送: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)

浙公网安备 33010602011771号