From 65d4ca25634f9a5e374afcf4431483cad490d7cd Mon Sep 17 00:00:00 2001 From: huangenjun <1021217094@qq.com> Date: Wed, 25 Feb 2026 11:32:56 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=B5=81=E5=BC=8F?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E4=B8=AD=20URL=20=E7=9A=84=20&=20=E8=A2=AB?= =?UTF-8?q?=E8=BD=AC=E4=B9=89=E4=B8=BA=20\u0026=20=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 jsonMarshalRaw 使用 SetEscapeHTML(false) 替代 json.Marshal, 避免 HTML 字符转义导致客户端无法直接使用返回的 URL。 Co-Authored-By: Claude Opus 4.6 --- .../internal/service/sora_gateway_service.go | 22 +++++++++++++++++-- .../service/sora_gateway_streaming_legacy.go | 4 ++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/backend/internal/service/sora_gateway_service.go b/backend/internal/service/sora_gateway_service.go index 04c4a9a9..b8241eef 100644 --- a/backend/internal/service/sora_gateway_service.go +++ b/backend/internal/service/sora_gateway_service.go @@ -1,6 +1,7 @@ package service import ( + "bytes" "context" "encoding/base64" "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 { 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 { return &ms, err } @@ -1052,6 +1053,23 @@ func (s *SoraGatewayService) normalizeSoraMediaURLs(urls []string) []string { 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 { switch mediaType { case "image": diff --git a/backend/internal/service/sora_gateway_streaming_legacy.go b/backend/internal/service/sora_gateway_streaming_legacy.go index 8a38f181..d399ba1c 100644 --- a/backend/internal/service/sora_gateway_streaming_legacy.go +++ b/backend/internal/service/sora_gateway_streaming_legacy.go @@ -316,7 +316,7 @@ func (s *SoraGatewayService) processSoraSSEData(data string, originalModel strin } } - updatedData, err := json.Marshal(payload) + updatedData, err := jsonMarshalRaw(payload) if err != nil { return "data: " + data, contentDelta, nil } @@ -484,7 +484,7 @@ func (s *SoraGatewayService) flushSoraRewriteBuffer(buffer string, originalModel if originalModel != "" { payload["model"] = originalModel } - updatedData, err := json.Marshal(payload) + updatedData, err := jsonMarshalRaw(payload) if err != nil { return "", "", err }