fix: 修复流式响应中 URL 的 & 被转义为 \u0026 的问题
新增 jsonMarshalRaw 使用 SetEscapeHTML(false) 替代 json.Marshal, 避免 HTML 字符转义导致客户端无法直接使用返回的 URL。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@@ -830,7 +831,7 @@ func (s *SoraGatewayService) writeSoraStream(c *gin.Context, model, content stri
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
encoded, _ := json.Marshal(chunk)
|
encoded, _ := jsonMarshalRaw(chunk)
|
||||||
if _, err := fmt.Fprintf(writer, "data: %s\n\n", encoded); err != nil {
|
if _, err := fmt.Fprintf(writer, "data: %s\n\n", encoded); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -851,7 +852,7 @@ func (s *SoraGatewayService) writeSoraStream(c *gin.Context, model, content stri
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
finalEncoded, _ := json.Marshal(finalChunk)
|
finalEncoded, _ := jsonMarshalRaw(finalChunk)
|
||||||
if _, err := fmt.Fprintf(writer, "data: %s\n\n", finalEncoded); err != nil {
|
if _, err := fmt.Fprintf(writer, "data: %s\n\n", finalEncoded); err != nil {
|
||||||
return &ms, err
|
return &ms, err
|
||||||
}
|
}
|
||||||
@@ -1052,6 +1053,23 @@ func (s *SoraGatewayService) normalizeSoraMediaURLs(urls []string) []string {
|
|||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jsonMarshalRaw 序列化 JSON,不转义 &、<、> 等 HTML 字符,
|
||||||
|
// 避免 URL 中的 & 被转义为 \u0026 导致客户端无法直接使用。
|
||||||
|
func jsonMarshalRaw(v any) ([]byte, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
enc := json.NewEncoder(&buf)
|
||||||
|
enc.SetEscapeHTML(false)
|
||||||
|
if err := enc.Encode(v); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Encode 会追加换行符,去掉它
|
||||||
|
b := buf.Bytes()
|
||||||
|
if len(b) > 0 && b[len(b)-1] == '\n' {
|
||||||
|
b = b[:len(b)-1]
|
||||||
|
}
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
func buildSoraContent(mediaType string, urls []string) string {
|
func buildSoraContent(mediaType string, urls []string) string {
|
||||||
switch mediaType {
|
switch mediaType {
|
||||||
case "image":
|
case "image":
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ func (s *SoraGatewayService) processSoraSSEData(data string, originalModel strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedData, err := json.Marshal(payload)
|
updatedData, err := jsonMarshalRaw(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "data: " + data, contentDelta, nil
|
return "data: " + data, contentDelta, nil
|
||||||
}
|
}
|
||||||
@@ -484,7 +484,7 @@ func (s *SoraGatewayService) flushSoraRewriteBuffer(buffer string, originalModel
|
|||||||
if originalModel != "" {
|
if originalModel != "" {
|
||||||
payload["model"] = originalModel
|
payload["model"] = originalModel
|
||||||
}
|
}
|
||||||
updatedData, err := json.Marshal(payload)
|
updatedData, err := jsonMarshalRaw(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user