用http方式实现websocket,如chatGPT时时打字效果,原生方式:fetch+sse+post

avatar
作者
猴君
阅读量:0

用http方式实现websocket,如chatGPT时时打字效果,原生方式:fetch+sse+post

fetch实现stream、原生fetch+sse+post

fetch 本身不直接支持流式输出,但你可以使用 ReadableStream 和 TextDecoder 等 Web Streams API 来实现类似的效果。

后端:比如python, php, java 等等都行...   核心是前端,在下面会有完整展示

from fastapi import FastAPI, Response from fastapi.responses import StreamingResponse import json import time from fastapi.middleware.cors import CORSMiddleware #解决跨域 from fastapi import FastAPI, File, UploadFile,Form,Request # from sse_starlette.sse import EventSourceResponse   app = FastAPI()   # 假设这是你想按事件流形式发送的JSON数据 data = {     "messages": [         {"text": "Hello, 1!", "timestamp": "2021-01-01T12:00:00"},         {"text": "Hello, 2!", "timestamp": "2021-01-02T12:00:01"},         {"text": "Hello, 3!", "timestamp": "2021-01-02T12:00:02"},     ] }  def generate_json_stream(data):     # 分割JSON数据,并逐个发送     for message in data["messages"]:         json_str = json.dumps(message)         yield json_str.encode("utf-8") #发送当前值给前端         time.sleep(1)  # 模拟延时   # 配置 CORSMiddleware 跨域 app.add_middleware(     CORSMiddleware,     allow_origins=["*"],        # 允许访问的源     allow_credentials=True,     # 支持 cookie     allow_methods=["*"],        # 允许使用的请求方法     allow_headers=["*"]         # 允许携带的 Headers )  @app.post("/stream-json") async def stream_json( request: Request,foo: str = Form(default='') ):            # 获取json         json_data = await request.json()     getHeader = request.headers     print('----1-----',json_data,getHeader)      # return EventSourceResponse(generate_json_stream(data), media_type="text/event-stream")     return StreamingResponse(generate_json_stream(data), media_type="text/event-stream")    if __name__ == "__main__":     import uvicorn     uvicorn.run(app, host="0.0.0.0", port=16887) 

核心是前端:

<!DOCTYPE html> <html> <head>   <title>原生fetch+sse+post</title> </head> <body>     <div id="messages"></div>   <button id="sendDataButton" onClick="send()">发送</button>  	<script> 	 	function send() { 	   		  msg='123465'; 			 		  // 发送 POST 请求 		  fetch('http://127.0.0.1:16887/stream-json', {//1、post提交 			 			method:"POST", 			body:JSON.stringify({ "content": msg}), 			timeout: 0, 			dataType:"text/event-stream", 			headers:{ 			  "Content-Type":"application/json" 			}, 			 		  }).then(response => {//2、post提交后返回的流 			 				// 检查响应是否成功 				if (!response.ok) { 				  throw new Error('网络响应异常'); 				} 				// 返回一个可读流 				return response.body; 			 		  }).then(body => {//3、对流进行时时打印 			 				//disableLoading();//开始打印数据 ...... 				 				//获取时时数据 				const reader = body.getReader(); 				 				// 时时打印 - 读取数据流 				function read() { 				   				  return reader.read().then(({ done, value }) => { 					// 检查是否读取完毕 					if (done) { 					  console.log('已传输完毕'); 					  return; 					} 					// 处理每个数据块 					console.log('收到的数据:', value); 					 					//把流处理成文本 					value_to_txt = new TextDecoder().decode(value) 					 					//json字符串 转 对象obj 					var resultObj = JSON.parse(value_to_txt);				 					console.log(resultObj); 						 					console.log('收到的数据 变成文本 :',  value_to_txt ); 					 					// 递归调用自身 - 继续读取下一个数据块 					read(); 					 				  }); 				} 				 				// 激活时时打印 - 开始读取数据流 				read(); 			 		  }).catch(error => {//捕捉异常 		  		console.error('Fetch 异常:', error); 		  }); 	} 	 	</script> </body> </html>

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!