前端处理POST类型的sse请求
想要编写一个类似于ChatGPT的聊天助手,但是不知道怎么处理SSE请求。问了GPT只给出了用EventSource的方法,但是这个只支持GET请求,由于发送的消息内容可能很长,因此使用了POST请求。为了达到目的,最后只能手写了fetch获取数据后进行处理。
fetch("/api/chat-message/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
message: this.newMessage.value,
}),
})
.then((response) => {
if (response.body === null) {
throw new Error("Response body is null");
}
const reader = response.body.getReader();
return new ReadableStream({
start(controller) {
function push() {
reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
const text = new TextDecoder("utf-8").decode(value);
console.log(text)
processText(text);
push();
});
}
push();
}
});
})
.catch((err) => {
alert("发送消息失败:" + err.message);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
主要流程如下:
- 使用
fetch
函数发送http POST请求。
fetch("/api/chat-message/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
message: this.newMessage.value,
}),
})
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- 使用一个reader,从body中直接读取原始二进制数据。
const reader = response.body.getReader();
1
- 读取消息
return new ReadableStream({
start(controller) {
function push() {
reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
const text = new TextDecoder("utf-8").decode(value);
console.log(text)
processText(text);
push();
});
}
push();
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- 在processText函数中处理消息
function processText(text) {
const lines = text.split("\n\n");
lines.forEach(line => {
if (line.startsWith("data: ")) {
const resp = JSON.parse(line.slice(6));
//在这里处理消息,每次收到消息都会调用这个函数
}
});
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
编辑 (opens new window)
上次更新: 2024/12/04, 16:28:16