尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Gin 如何用 PureJSON 输出字面量 HTML 特殊字符而不是 JSON 默认转义

Gin 如何用 PureJSON 输出字面量 HTML 特殊字符而不是 JSON 默认转义 Gin 如何用 PureJSON 输出字面量 HTML 特殊字符而不是 JSON 默认转义【免费下载链接】ginGin is a high-performance HTTP web framework written in Go. It provides a Martini-like API but with significantly better performance—up to 40 times faster—thanks to httprouter. Gin is designed for building REST APIs, web applications, and microservices.项目地址: https://gitcode.com/GitHub_Trending/gi/gin当你用 Gin 的c.JSON返回包含、、的字符串时响应体里看到的全是\u003c、\u003e、\u0026这类 Unicode 转义前端拿到后需要再还原一次。如果你的接口直接面向 JSON 消费者而不是把 JSON 嵌进 HTML 里这些转义只会干扰可读性。Gin 提供c.PureJSON来解决这个问题它在序列化前关闭 HTML 转义让特殊字符以字面量形式输出。本文基于本仓库的 docs/doc.md 中 PureJSON 章节、渲染器实现与测试断言给出一条可运行、可核对的最小操作路径。当前仓库 go.mod 声明go 1.25.0文档中提到的 Go 1.6 限制见下文对当前版本自然满足。为什么c.JSON会把 HTML 特殊字符转义先明确默认行为是什么。Gin 的 JSON 编码器接口对SetEscapeHTML的注释写得很清楚codec/json/api.go默认行为是把、、转义为\u0026、\u003c、\u003e以避免把 JSON 嵌入 HTML 时可能引发的安全问题在转义影响可读性的非 HTML 场景下调用SetEscapeHTML(false)关闭这一行为。c.JSON走的是Marshal路径保留默认转义。仓库测试 context_test.go 里的TestContextRenderJSON就是这条默认行为的断言输入H{foo: bar, html: b}期望响应体为{foo:bar,html:\u003cb\u003e}Content-Type为application/json; charsetutf-8。这就是你遇到字面量变转义现象的直接来源。PureJSON 的实现路径c.PureJSON在 context.go 中定义为// PureJSON serializes the given struct as JSON into the response body. // PureJSON, unlike JSON, does not replace special html characters with their unicode entities. func (c *Context) PureJSON(code int, obj any) { c.Render(code, render.PureJSON{Data: obj}) }而渲染器 render/json.go 的PureJSON.Render做三件事写入Content-Type: application/json; charsetutf-8通过当前 JSON codec 创建Encoder调用encoder.SetEscapeHTML(false)调用encoder.Encode(r.Data)。注意Encode与Marshal不同它会在 JSON 编码后追加一个换行符codec/json/api.go 的注释。所以PureJSON的响应体比c.JSON多一个结尾换行仓库测试 render_test.go 的期望值{foo:bar,html:b}后正是带\n的。写一个最小示例并核对输出下面这个程序直接取自 docs/doc.md 的 PureJSON 章节同时挂上/json和/purejson两条路由方便对比转义前后的差异。保存为独立目录中的main.gogo mod initgo get github.com/gin-gonic/gin然后运行package main import ( net/http github.com/gin-gonic/gin ) func main() { r : gin.Default() // Serves unicode entities r.GET(/json, func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ html: bHello, world!/b, }) }) // Serves literal characters r.GET(/purejson, func(c *gin.Context) { c.PureJSON(http.StatusOK, gin.H{ html: bHello, world!/b, }) }) // listen and serve on 0.0.0.0:8080 r.Run(:8080) }go run .启动后分别请求两条路由curl http://localhost:8080/json curl http://localhost:8080/purejson判断标准以仓库测试断言为准c.JSON对html: b的期望输出是转义形式\u003cb\u003econtext_test.goc.PureJSON的期望输出是字面量b且Content-Type为application/json; charsetutf-8context_test.go 的TestContextRenderPureJSON。如果/json返回\u003c...\u003e而/purejson返回...说明行为与文档一致。需要中断响应链时AbortWithStatusPureJSON如果你的场景是中间件里校验失败后要中断链 返回未转义 JSON可以用AbortWithStatusPureJSON。context.go 中的注释说明它先调用Abort()再内部调用PureJSON停止处理链、写入状态码并返回不带转义的 JSON body同时把Content-Type设为application/json。对应测试 TestContextAbortWithStatusPureJSON 断言了响应体未被转义{foo:fooValue,bar:barValue}形式的明文输出且上下文处于 aborted 状态。可选分支替换 JSON codec 时 PureJSON 是否仍生效Gin 默认用encoding/json也可以按 docs/doc.md 的 Build Tags 章节在构建时替换 codecgo build -tagsjsoniter . # 或 go build -tagsgo_json . # 或 go build -tagssonic .PureJSON.Render不是直接调用encoding/json而是走 codec 抽象的json.API.NewEncoder(w)再SetEscapeHTML(false)见上文 render/json.go。各 codec 实现如 codec/json/jsoniter.go 使用jsoniter.ConfigCompatibleWithStandardLibrary都返回实现了同一Encoder接口的对象该接口的SetEscapeHTML语义在 codec/json/api.go 中统一注明。因此按上述 build tag 替换 codec 构建时PureJSON的关闭转义逻辑仍然走同一接口路径。限制与核对清单文档明确说明This feature is unavailable in Go 1.6 and lower即 PureJSON 需要 Go 1.6 以上当前仓库要求 Go 1.25.0go.mod正常拉取构建即可满足。PureJSON输出带一个结尾换行符Encode行为这是与c.JSON输出的已知差异来自 codec/json/api.go 的注释与 render_test.go 的断言。两种渲染器Content-Type都是application/json; charsetutf-8区别只在是否转义不要依赖Content-Type来区分二者。不依赖跑服务也可以核对在本仓库根目录执行go test -run TestRenderPureJSON ./render/和go test -run TestContextRenderPureJSON .两条测试分别对应渲染器与Context层的字面量输出断言。如果你发现/purejson的输出仍被转义先确认代码路径确实改成了c.PureJSON而不是c.JSON文档中AbortWithStatusPureJSON注释里 return a JSON body without escaping 的描述表明未转义行为是纯PureJSON渲染路径的预期而非配置项可切换的选项。【免费下载链接】ginGin is a high-performance HTTP web framework written in Go. It provides a Martini-like API but with significantly better performance—up to 40 times faster—thanks to httprouter. Gin is designed for building REST APIs, web applications, and microservices.项目地址: https://gitcode.com/GitHub_Trending/gi/gin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表