114 lines
3.0 KiB
JavaScript
114 lines
3.0 KiB
JavaScript
|
import axios from 'axios'
|
|||
|
import { fetchEventSource } from '@microsoft/fetch-event-source'
|
|||
|
|
|||
|
const service = axios.create({
|
|||
|
baseURL: process.env.VITE_APP_BASE_API,
|
|||
|
timeout: 30000
|
|||
|
})
|
|||
|
|
|||
|
// 请求拦截器
|
|||
|
service.interceptors.request.use(
|
|||
|
config => {
|
|||
|
// 如果配置中已经包含了 Authorization header,则使用配置中的值
|
|||
|
if (!config.headers['Authorization']) {
|
|||
|
const token = localStorage.getItem('token')
|
|||
|
if (token) {
|
|||
|
config.headers['Authorization'] = `Bearer ${token}`
|
|||
|
}
|
|||
|
}
|
|||
|
config.headers['Content-Type'] = 'application/json'
|
|||
|
return config
|
|||
|
},
|
|||
|
error => {
|
|||
|
return Promise.reject(error)
|
|||
|
}
|
|||
|
)
|
|||
|
|
|||
|
// 响应拦截器
|
|||
|
service.interceptors.response.use(
|
|||
|
response => {
|
|||
|
return response.data
|
|||
|
},
|
|||
|
error => {
|
|||
|
return Promise.reject(error)
|
|||
|
}
|
|||
|
)
|
|||
|
|
|||
|
// SSE 请求方法
|
|||
|
export const sseRequest = (config) => {
|
|||
|
return new Promise((resolve) => {
|
|||
|
try {
|
|||
|
const url = new URL(`${config.url}`, window.location.origin)
|
|||
|
const ctrl = new AbortController()
|
|||
|
let messageQueue = []
|
|||
|
let resolveQueue = null
|
|||
|
|
|||
|
const messageGenerator = async function* () {
|
|||
|
const source = new fetchEventSource(url.toString(), {
|
|||
|
method: 'POST',
|
|||
|
headers: {
|
|||
|
'Authorization': config.headers?.Authorization || `Bearer ${localStorage.getItem('token')}`,
|
|||
|
'Content-Type': 'application/json',
|
|||
|
'Accept': 'text/event-stream'
|
|||
|
},
|
|||
|
body: JSON.stringify(config.params),
|
|||
|
signal: ctrl.signal,
|
|||
|
openWhenHidden: true,
|
|||
|
onmessage: (event) => {
|
|||
|
try {
|
|||
|
const data = JSON.parse(event.data)
|
|||
|
if (resolveQueue) {
|
|||
|
resolveQueue(data)
|
|||
|
resolveQueue = null
|
|||
|
} else {
|
|||
|
messageQueue.push(data)
|
|||
|
}
|
|||
|
} catch (error) {
|
|||
|
console.error('Error parsing SSE message:', error)
|
|||
|
}
|
|||
|
},
|
|||
|
onerror: (error) => {
|
|||
|
console.error('EventSource failed:', error)
|
|||
|
ctrl.abort()
|
|||
|
if (resolveQueue) {
|
|||
|
resolveQueue(null)
|
|||
|
resolveQueue = null
|
|||
|
}
|
|||
|
},
|
|||
|
onclose: () => {
|
|||
|
console.log('Connection closed')
|
|||
|
if (resolveQueue) {
|
|||
|
resolveQueue(null)
|
|||
|
resolveQueue = null
|
|||
|
}
|
|||
|
}
|
|||
|
})
|
|||
|
|
|||
|
try {
|
|||
|
while (true) {
|
|||
|
if (messageQueue.length > 0) {
|
|||
|
yield messageQueue.shift()
|
|||
|
} else {
|
|||
|
const message = await new Promise(resolve => {
|
|||
|
resolveQueue = resolve
|
|||
|
})
|
|||
|
if (message === null) {
|
|||
|
break
|
|||
|
}
|
|||
|
yield message
|
|||
|
}
|
|||
|
}
|
|||
|
} finally {
|
|||
|
ctrl.abort()
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
resolve(messageGenerator())
|
|||
|
} catch (error) {
|
|||
|
console.error('SSE request setup failed:', error)
|
|||
|
resolve((async function* () {})())
|
|||
|
}
|
|||
|
})
|
|||
|
}
|
|||
|
|
|||
|
export default service
|