elli 请求参数解析完整教程:GET/POST 参数、URI 解码与表单处理的实战清单

elli 请求参数解析完整教程:GET/POST 参数、URI 解码与表单处理的实战清单

【免费下载链接】elli Simple, robust and performant Erlang web server 【免费下载链接】elli 项目地址: https://gitcode.com/gh_mirrors/ell/elli

elli 是一个简单、健壮且高性能的 Erlang Web 服务器,专为 HTTP API 场景设计。本教程将围绕 elli 请求参数解析 这一核心主题,用最少的代码带你掌握 GET 参数、POST 参数、URI 解码与表单处理的全部技巧,并附上一份可以直接抄作业的实战清单。无论你是 Erlang 新手,还是刚接触 elli 的普通用户,读完本文都能在自己的回调函数里轻松搞定参数读取。

一、先认识 elli 的请求对象与回调入口

在 elli 中,每个 HTTP 请求都会被封装为一个 #req{} 记录,定义在 elli.hrl 中,其中与参数解析最相关的字段是:

  • args:URL 查询字符串解析后的参数列表(GET 参数)
  • body:请求体二进制数据(POST 数据来源)
  • headers:请求头列表
  • raw_path:包含查询字符串的原始路径

而所有参数读取的便捷函数都集中在 elli_request.erl 这个模块里。你的回调函数只要实现 handle/2,就能拿到 Req 并调用这些函数,参考 elli_example_callback.erl 的写法:

handle(Req, _Args) ->
    handle(Req#req.method, elli_request:path(Req), Req).

二、GET 参数解析:三种常用姿势

GET 参数来自 URL 的查询字符串,比如 /hello?name=knut。elli 在收到请求时就会自动完成解析,把结果放进 args 字段,解析逻辑见 elli_http.erl 中的 split_args/1

姿势 1:get_arg/2、get_arg/3 读取单个参数

这是最常用的方式,第二个参数是默认值,当参数不存在时返回默认值:

Name = elli_request:get_arg(<<"name">>, Req, <<"undefined">>),
{ok, [], <<"Hello ", Name/binary>>}.

姿势 2:get_args/1 一次拿到全部参数

返回一个 proplist,便于批量处理或循环遍历:

Args = elli_request:get_args(Req),
%% 例如 [{<<"name">>, <<"knut">>}, {<<"foo">>, true}]

姿势 3:无值参数返回 true

这是 elli 的一个贴心设计:对于 ?foo 这种没有 = 的参数,解析结果为 {<<"foo">>, true},你可以据此判断某个开关参数是否被携带。对应测试见 elli_tests.erl 中的 get_args() 用例。

三、URI 解码实战:get_arg_decoded 系列

URL 中的特殊字符会被编码,例如空格变成 %20= 变成 %3D。如果你直接用 get_arg 读取,拿到的是原始编码值,中文和特殊字符会乱码。这时就该用 URI 解码 版本的函数:

%% 请求 /decoded-hello?name=knut%3D
Name = elli_request:get_arg_decoded(<<"name">>, Req, <<"undefined">>),
%% 结果 Name = <<"knut=">>,而不是 <<"knut%3D">>

对应的批量解码函数是 get_args_decoded/1,它会遍历整个参数列表并逐一解码。底层实现调用了 Erlang 自带的 http_uri:decode/1(见 elli_request.erl 第 77-82 行)。

黄金法则:凡是参数值可能包含中文、空格或特殊符号,一律优先使用 *_decoded 系列函数,避免乱码坑。

四、POST 参数解析与表单处理:完整方案

POST 参数藏在请求体(body)中,elli 不会自动解析,需要显式调用。表单处理的核心是 body_qs/1:它先检查 Content-Type 是否为 application/x-www-form-urlencoded,然后调用 split_args/1 把 body 拆成参数列表(见 elli_request.erl 第 84-94 行)。

单个 POST 参数:post_arg/3

Name = elli_request:post_arg(<<"name">>, Req, <<"undefined">>),

解码版本:post_arg_decoded/3

%% body 为 name=foo&city=New%20York
City = elli_request:post_arg_decoded(<<"city">>, Req, <<"undefined">>),
%% 结果 City = <<"New York">>

全部 POST 参数:post_args/1 与 post_args_decoded/1

All = elli_request:post_args_decoded(Req),

⚠️ 重要提示body_qs/1 只有在 Content-Type 正确时才工作。如果客户端忘了设置 application/x-www-form-urlencoded,它会直接抛出 badarg。因此 POST 场景下务必确保前端正确设置请求头,这也是表单处理最常见的报错原因。

五、实战清单:照抄就能用的完整示例

参考 elli_example_callback.erl 第 39-44 行的 POST 示例,下面是一份完整的参数处理回调:

%% GET 带解码:/hello?name=张三
handle('GET', [<<"hello">>], Req) ->
    Name = elli_request:get_arg_decoded(<<"name">>, Req, <<"world">>),
    {ok, [], <<"Hello ", Name/binary>>};

%% POST 表单:name=foo&city=New%20York
handle('POST', [<<"hello">>], Req) ->
    Name = elli_request:post_arg(<<"name">>, Req, <<"undefined">>),
    City = elli_request:post_arg_decoded(<<"city">>, Req, <<"undefined">>),
    {ok, [], <<"Hello ", Name/binary, " of ", City/binary>>};

对应的自动化测试(elli_tests.erl 中的 post_args())验证了返回结果是 Hello foo of New York,证明整条链路完全可用。

六、进阶技巧与常见坑清单

场景推荐函数注意事项
读取单个 GET 参数get_arg/2,3返回二进制,未命中给默认值
解码 GET 参数get_arg_decoded/2,3中文/特殊字符必用
读取全部 GET 参数get_args/1无值参数为 true
读取单个 POST 参数post_arg/2,3依赖正确 Content-Type
解码 POST 参数post_arg_decoded/2,3表单处理首选
读取原始查询串query_str/1? 后面的原文
读取请求头get_header/2,3键值为二进制

最后提醒:elli 的参数解析 API 设计得非常克制——每个函数都有「普通版」和「解码版」两种,普通版速度快、解码版更安全。只要记住「有编码就解码」这条原则,再结合本文的实战清单,你就能在 elli 中游刃有余地处理 GET/POST 参数与表单数据了。

【免费下载链接】elli Simple, robust and performant Erlang web server 【免费下载链接】elli 项目地址: https://gitcode.com/gh_mirrors/ell/elli

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值