88 lines
2.0 KiB
JavaScript
88 lines
2.0 KiB
JavaScript
|
|
import { getToken } from '@/common/common.js'
|
|
import { get_base_url } from '@/api/request'
|
|
|
|
const base_url = get_base_url();
|
|
const token = getToken();
|
|
// 基础配置
|
|
const baseConfig = {
|
|
enableChunked: true, // 必须开启分块传输
|
|
responseType: 'arraybuffer', // 微信小程序需用arraybuffer
|
|
timeout: 30000 // 超时时间延长
|
|
}
|
|
|
|
// 流式请求核心实现
|
|
function streamRequest(options) {
|
|
const {
|
|
url,
|
|
method = 'GET',
|
|
data,
|
|
headers = {},
|
|
onChunk,
|
|
onComplete,
|
|
onError
|
|
} = options
|
|
|
|
headers['Accept'] = 'text/event-stream'
|
|
headers['Content-Type'] = 'application/json;charset=UTF-8'
|
|
headers['summary'] = token
|
|
|
|
// 创建请求任务
|
|
const requestTask = uni.request({
|
|
url,
|
|
method,
|
|
data,
|
|
header: headers,
|
|
...baseConfig,
|
|
success: (res) => {
|
|
onComplete?.(res)
|
|
},
|
|
fail: (err) => {
|
|
onError?.(err)
|
|
}
|
|
})
|
|
console.log(requestTask)
|
|
// 流式数据处理器
|
|
let bufferCache = ''
|
|
requestTask.onChunkReceived((res) => {
|
|
try {
|
|
// ArrayBuffer转字符串(兼容多平台)
|
|
const uint8Array = new Uint8Array(res.data)
|
|
const chunkText = bufferCache +
|
|
String.fromCharCode.apply(null, uint8Array)
|
|
|
|
// 处理SSE格式数据(data:开头)
|
|
const events = chunkText.split('\n\n')
|
|
bufferCache = events.pop() || '' // 缓存不完整数据
|
|
|
|
events.forEach(event => {
|
|
if (event.startsWith('data:')) {
|
|
onChunk?.(event.substring(5).trim())
|
|
}
|
|
})
|
|
} catch (e) {
|
|
onError?.(e)
|
|
}
|
|
})
|
|
|
|
return {
|
|
abort: () => requestTask.abort()
|
|
}
|
|
}
|
|
|
|
// 使用示例
|
|
export const demoUsage = (data) => {
|
|
const controller = streamRequest({
|
|
url: `${base_url}/trastudy/intgask/askAbout`,
|
|
data: data,
|
|
onChunk: (chunk) => {
|
|
console.log('收到数据块:', chunk)
|
|
// 实时更新UI逻辑
|
|
},
|
|
onComplete: () => console.log('传输完成'),
|
|
onError: (err) => console.error('错误:', err)
|
|
})
|
|
|
|
// 需要中断时调用
|
|
// controller.abort()
|
|
} |