You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang解析Nginx日志中非法URL字符串失败的解决方法咨询

问题根源

你的JSON字符串解析失败,是因为URI字段中包含非法的JSON转义序列。JSON规范要求\x后面必须紧跟两个合法的十六进制字符(0-9、a-f、A-F),但示例中的\xG8、\xQ1等序列里,G、Q并非十六进制字符,导致json.Unmarshal无法识别,抛出invalid character 'x' in string escape code错误。

解决方案

1. 从日志生成源头修复(推荐)

如果能控制Nginx的日志输出配置,直接让Nginx生成合法的JSON格式日志:
在Nginx的log_format中添加escape=json参数,它会自动将URI中的特殊字符转成符合JSON规范的转义序列:

log_format json_log '{"time":"$time_iso8601","method":"$request_method","uri":"$uri"}';
access_log /var/log/nginx/access.log json_log escape=json;

这样生成的日志不会出现非法转义,Golang的标准json.Unmarshal可以直接解析。

2. 预处理非法JSON字符串(适用于已生成的日志)

如果日志已经存在,无法修改生成逻辑,可以在解析前预处理字符串,修复非法的\x转义:

import (
    "log"
    "regexp"
    "strconv"
    "encoding/json"
)

type Data map[string]interface{}

func fixInvalidJSONEscapes(s string) string {
    // 匹配所有 \x 后跟非十六进制字符的序列
    re := regexp.MustCompile(`\\x([0-9a-fA-F]{0,2}|[^0-9a-fA-F]{2})`)
    return re.ReplaceAllStringFunc(s, func(m string) string {
        if len(m) != 4 {
            return m
        }
        chars := m[2:]
        // 尝试将字符转成合法的UTF-8转义
        var result string
        for _, c := range chars {
            if c < 128 {
                result += string(c)
            } else {
                // 转成 \u 开头的Unicode转义
                result += "\\u" + strconv.FormatInt(int64(c), 16)
            }
        }
        return result
    })
}

func main() {
    str := "{\"time\":\"2023-07-20T10:11:29+08:00\",\"method\":\"GET\",\"uri\":\"/www.baidu.com/eu\\\\xG8\\\\xB8\\\\xE9\\\\xQ1\\\\x9F\\\\xZ7\\\\xE8\\\\xAE\\\\xCF\\\\xF9\\\\xB5\\\\x12\"}"
    data := make(Data)

    fixedStr := fixInvalidJSONEscapes(str)
    if err := json.Unmarshal([]byte(fixedStr), &data); err == nil {
        log.Printf("json success, %#v", data)
    } else {
        log.Print(err)
    }
}

3. 使用宽松的JSON解析库

如果预处理逻辑复杂,可以选择支持非严格JSON解析的第三方库,比如gjson,它能直接提取字段值,忽略非法转义:

import (
    "log"
    "github.com/tidwall/gjson"
)

func main() {
    str := "{\"time\":\"2023-07-20T10:11:29+08:00\",\"method\":\"GET\",\"uri\":\"/www.baidu.com/eu\\\\xG8\\\\xB8\\\\xE9\\\\xQ1\\\\x9F\\\\xZ7\\\\xE8\\\\xAE\\\\xCF\\\\xF9\\\\xB5\\\\x12\"}"
    
    result := gjson.Parse(str)
    time := result.Get("time").String()
    method := result.Get("method").String()
    uri := result.Get("uri").String()
    
    log.Printf("time: %s, method: %s, uri: %s", time, method, uri)
}

内容的提问来源于stack exchange,提问作者moluzhui

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:23:19