Params

虽然查询被指定为纯字符串,但它通常被解释为一组键值对,通常称为 URL 参数,尽管在这里我们使用术语查询参数或简称 params。关于查询参数格式,没有官方的标准规范,但 W3C 建议和 HTML 5 有如下说明

  • 查询字符串由一系列键值对组成。

  • 在每对中,字段名称和值用等号“=”分隔。

  • 一系列对用 & 符号“&”分隔。

  • 大多数 Web 框架允许多个值具有相同的键。

  • 键比较通常区分大小写,但接收机构最终负责决定这一点。

此 URL 有两个查询参数,分别是 firstlast,它们的值分别为 “John” 和 “Doe”

https://www.example.com?first=John&last=Doe
s params( s )

"?first=John&last=Doe"

{ { "first", "John" }, { "last", "Doe" } }

与路径类似,库允许使用这些单独的双向视图类型访问参数,这些类型引用底层 URL

类型 访问器 描述

params_view

params

解码参数的只读范围。

params_ref

params

可修改的解码参数范围。

params_encoded_view

encoded_params

参数的只读范围。

params_encoded_ref

encoded_params

可修改的参数范围。

参数始终具有键,即使它是空字符串。值是可选的;空字符串与没有值不同。查询参数中缺少 = 字符被解释为没有值,而带有 = 字符但没有值则被解释为空字符串。

s params( s )

"?name=John"

{ { "name", "John" } }

"?=John"

{ { "", "John" } }

"?name="

{ { "name", "" } }

"?name"

{ { "name", no_value } }

"?"

{ { "", no_value } }

""

{}

为了表示单个参数,库使用这些类型,这些类型通过其所有权模型以及是否可能进行百分号转义来区分

类型 字符串类型 描述

param

std::string

具有字符串所有权的键值对。这可以用于保存解码后的字符串,或允许调用者通过复制来获取参数的所有权。

param_view

string_view

不带百分号转义的键值对,引用外部管理的字符缓冲区。

param_pct_view

pct_string_view

可能包含百分号转义的键值对,引用外部管理的字符缓冲区。

参数类型可以从初始化列表构造,从而实现方便的表示法。为了表示缺少值,可以使用常量 no_valuenullptr。下表显示了一些用于构造参数类型的初始化列表示例,以及生成的数据成员

语句 qp.key qp.value qp.has_value

param qp = { "first", "John" };

“First”

“John”

true

param qp = { "first", "" };

“First”

""

true

param qp = { "first", no_value };

“First”

""

false

param qp = { "", "Doe" };

""

“Doe”

true

为了理解查询与生成的参数范围之间的关系,首先我们定义这个函数 parms,它返回与参数容器中元素对应的参数列表

auto parms( core::string_view s ) -> std::list< param >
{
    url_view u( s );
    std::list< param > seq;
    for( auto qp : u.params() )
        seq.push_back( qp );
    return seq;
}

在下表中,我们展示了使用不同查询调用 parms 的结果。这演示了查询的语法如何映射到参数结构

s params( s )

"?first=John&last=Doe"

{ { "first", "John" }, { "last", "Doe" } }

"?id=42&unsorted"

{ { "id", "42" }, { "last", no_value } }

"?col=cust&row="

{ { "col", "cust" }, { "row", "" } }

"?justify=left&"

{ { "justify", "left" }, { "", no_value } }

"?"

{ { "", no_value } }

""

{ }

一个空的查询字符串(“?”)产生一个带有空参数的序列,这可能令人惊讶。这是设计使然,否则该序列将无法与没有查询字符串的情况区分开来(上表中的最后两行)。

有关用于将查询字符串表示为参数的容器的完整详细信息,请查看参考。