Histórico (questão mais abaixo)
Eu tenho pesquisado isso no Google e para trás lendo RFCs e perguntas SO tentando decifrar isso, mas ainda não entendi.
Acho que votamos na "melhor" resposta e pronto, ou?
Basicamente, tudo se resume a isso.
3.4. Componente de Consulta
O componente de consulta é uma string de informações a ser interpretada pelo recurso.
query = *uric
Em um componente de consulta, os caracteres ";", "/", "?", ":", "@", "&", "=", "+", "," E "$" são reservados.
A primeira coisa que me deixa perplexo é que * úrico é definido assim
uric = reserved | unreserved | escaped
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
No entanto, isso é um pouco esclarecido por parágrafos como
A classe de sintaxe "reservada" acima se refere aos caracteres permitidos em um URI, mas que podem não ser permitidos em um determinado componente da sintaxe genérica do URI; eles são usados como delimitadores dos componentes descritos na Seção 3.
Os caracteres no conjunto "reservado" não são reservados em todos os contextos. O conjunto de caracteres realmente reservados em qualquer componente URI é definido por esse componente. Em geral, um caractere é reservado se a semântica do URI mudar se o caractere for substituído por sua codificação US-ASCII de escape.
Este último trecho parece um pouco retrógrado, mas afirma claramente que o conjunto de caracteres reservados depende do contexto. Ainda assim, 3.4 afirma que todos os caracteres reservados são reservados dentro de um componente de consulta, entretanto, a única coisa que mudaria a semântica aqui é escapar do ponto de interrogação (?), Já que URIs não definem o conceito de uma string de consulta.
Neste ponto, desisti totalmente dos RFCs, mas achei o RFC 1738 particularmente interessante.
Um URL HTTP assume o formato:
http://<host>:<port>/<path>?<searchpart>
Nos componentes <path> e <searchpart>, "/", ";", "?" são reservados. O caractere "/" pode ser usado em HTTP para designar uma estrutura hierárquica.
Eu interpreto isso pelo menos em relação aos URLs HTTP que o RFC 1738 substitui o RFC 2396. Como a consulta URI não tem noção de uma string de consulta, a interpretação de reservado realmente não me permite definir strings de consulta como estou acostumado fazendo agora.
Questão
Isso tudo começou quando eu queria passar uma lista de números junto com a solicitação de outro recurso. Eu não pensei muito nisso e apenas passei como valores separados por vírgula. Para minha surpresa, embora a vírgula tenha escapado. A consulta page.html?q=1,2,3
codificada page.html?q=1%2C2%2C3
funcionou, mas é feia e não esperava. Foi quando comecei a examinar os RFCs.
Minha primeira pergunta é simplesmente: codificar vírgulas é realmente necessário?
Minha resposta, de acordo com RFC 2396: sim, de acordo com RFC 1738: não
Mais tarde encontrei posts relacionados com a passagem de listas entre pedidos. Onde a abordagem csv era considerada ruim. Em vez disso, apareceu (não vi isso antes).
page.html?q=1;q=2;q=3
Minha segunda pergunta, este é um URL válido?
Minha resposta, de acordo com RFC 2396: não, de acordo com RFC 1738: não (; é reservado)
Não tenho problemas em passar o csv, contanto que seja números, mas sim, você corre o risco de ter que codificar e decodificar valores para frente e para trás se a vírgula de repente for necessária para outra coisa. De qualquer forma, tentei fazer a string de consulta de ponto-e-vírgula com ASP.NET e o resultado não foi o que eu esperava.
Default.aspx?a=1;a=2&b=1&a=3
Request.QueryString["a"] = "1;a=2,3"
Request.QueryString["b"] = "1"
Não consigo ver como isso difere muito de uma abordagem csv, pois quando peço "a", recebo uma string com vírgulas. ASP.NET certamente não é uma implementação de referência, mas ainda não me decepcionou.
Mas o mais importante - minha terceira pergunta - onde estão as especificações para isso? e o que você faria ou não faria?