记录uniapp小程序SSE流式响应问题

952 阅读1分钟

前言

记录一下uniapp 小程序SEE方式请求问题,目前这个代码运行到开发者工具是有效果的。

以下是主要请求代码:

getMessage() {
               //请求方法
                let requestTask = uni.request({
				url:'请求链接',
				enableChunked:true,//微信小程序支持SSE
				 header: {
				    Accept: 'text/event-stream',
                                      'Content-type':'application/json',
                                      'X-API-KEY': ''
				},
				responseType: 'arraybuffer',
				method:'get',
				success( res ) {
					console.log('请求完毕', res)
				}
			})
			requestTask.onHeadersReceived(res => {
			   console.log('onHeadersReceived', res)	
			})
			
			requestTask.onChunkReceived(res => {
				const arrayBuffer = res.data;
				const uint8Array = new Uint8Array(arrayBuffer);
				let data = uni.arrayBufferToBase64(uint8Array);
				data = new Buffer(data, 'base64');
				data = data.toString('utf8');
				const lines = data.split("\n\n");
				
				lines.forEach(line => {
					if( line.indexOf('{') != -1 ){
						// 使用正则表达式提取 data 部分
						const dataMatch = line.match(/data:(\{.*\})/);
						// 检查是否成功匹配
						if (dataMatch && dataMatch[1]) {
						    const dataString = dataMatch[1];
                                              console.log('content -->', this.parseSSEData(dataString))

						} else {
						    console.error('未找到 data 部分');
						}
					}
				})
			})
		// #endif`
         },
                    
                    
                    
       //转换返回结构的方法
      parseSSEData (data){
		try {
			const parsed = JSON.parse(data)
			
			const directReasoning = parsed.choices?.[0]?.delta?.reasoning_content
			if (directReasoning) {
				return {
					id: parsed.id,
					content: parsed.choices?.[0]?.delta?.content || ''
				}
			}
			
			const content = parsed.choices?.[0]?.delta?.content || ''
			
			// 处理 think 标签包裹的情况
			if (content.includes('<think>')) {
				this.isInThinkTag = true
				const startIndex = content.indexOf('<think>') + '<think>'.length
				return {
					id: parsed.id,
					content: content.substring(0, content.indexOf('<think>'))
				}
			}
			
			if (content.includes('</think>')) {
				this.isInThinkTag = false
				const endIndex = content.indexOf('</think>')
				return {
					id: parsed.id,
					content: content.substring(endIndex + '</think>'.length)
				}
			}
			
			// 根据状态决定内容归属
			return {
				id: parsed.id,
				content: this.isInThinkTag ? '' : content
			}
		} catch (e) {
			console.error('解析JSON失败:', e)
			return null
		}
	},`
            
            
            

最终打印出来就有值了

image.png