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

POST请求JSON数据提取失败及Content-Type校验问题

在Zig HTTP服务中读取JSON请求并校验Content-Type

一、校验Content-Type请求头

要确认请求的Content-Type是否为application/json,可以通过request.headers的getFirstValue方法获取对应字段值,再做字符串比对:

pub fn post(response: *http.Server.Response) void {
    response.do() catch |e| {
        std.log.err("{any}", .{e});
        return;
    };

    if (response.request.method != .HEAD) {
        // 获取Content-Type字段
        const content_type = response.request.headers.getFirstValue("Content-Type") orelse {
            std.log.err("Missing Content-Type header", .{});
            response.status = .unsupported_media_type;
            return;
        };

        // 校验是否为application/json
        if (!std.mem.eql(u8, content_type, "application/json")) {
            std.log.err("Invalid Content-Type: expected application/json", .{});
            response.status = .unsupported_media_type;
            return;
        }

        std.log.debug("Valid JSON request received", .{});
    }
}

二、读取并解析JSON内容

Zig HTTP服务的请求体需要通过response.reader()读取,结合请求头中的content_length指定长度获取数据,再用std.json模块解析为对应结构体:

1. 定义JSON对应的结构体

先声明与请求JSON结构匹配的Zig结构体:

const LoginRequest = struct {
    login: []const u8,
    password: []const u8,
};

2. 读取请求体并解析JSON

在处理函数中添加读取和解析逻辑:

pub fn post(response: *http.Server.Response) void {
    response.do() catch |e| {
        std.log.err("{any}", .{e});
        return;
    };

    if (response.request.method != .HEAD) {
        // 省略Content-Type校验代码(同上)

        const reader = response.reader();
        var gpa = std.heap.GeneralPurposeAllocator(.{}){};
        defer _ = gpa.deinit();
        const allocator = gpa.allocator();

        // 根据content_length读取完整请求体
        const body = reader.readAllAlloc(allocator, response.request.content_length orelse 0) catch |e| {
            std.log.err("Failed to read request body: {any}", .{e});
            response.status = .bad_request;
            return;
        };
        defer allocator.free(body);

        // 解析JSON到结构体
        const parsed_request = std.json.parse(LoginRequest, &std.json.TokenStream.init(body), .{ .allocator = allocator }) catch |e| {
            std.log.err("Failed to parse JSON: {any}", .{e});
            response.status = .bad_request;
            return;
        };
        defer parsed_request.deinit();

        // 使用解析后的数据
        std.log.info("Login: {s}, Password: {s}", .{ parsed_request.value.login, parsed_request.value.password });
    }
}

注意事项

  • 若请求采用分块传输编码(content_length为null),需循环读取直到流结束
  • 所有通过分配器申请的内存要记得及时释放,避免泄漏
  • 可根据需求调整std.json.ParseOptions参数,比如忽略未知字段

内容的提问来源于stack exchange,提问作者Hasan A Yousef

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 14:21:26