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?
fonte
Respostas:
O fato de um caractere ser reservado em um componente de URL genérico não significa que ele deva ser escapado quando aparecer dentro do componente ou nos dados do componente. O caractere também deve ser definido como um delimitador dentro da sintaxe genérica ou específica do esquema e a aparência do caractere deve estar dentro dos dados.
O padrão atual para URIs genéricos é RFC 3986 , que tem o seguinte significado:
Assim, as vírgulas são explicitamente permitidas em strings de consulta e só precisam ter escape nos dados se esquemas específicos definem-no como um delimitador. O esquema HTTP não usa vírgula ou ponto e vírgula como delimitador em strings de consulta, portanto, não é necessário escapar o escape. Se os navegadores seguem esse padrão é outra questão.
Usar CSV deve funcionar bem para dados de string, você só precisa seguir as convenções CSV padrão e colocar os dados entre aspas ou escapar das vírgulas com barras invertidas.
Quanto ao RFC 2396, ele também permite vírgulas sem escape em strings de consulta HTTP:
Visto que as vírgulas não têm um propósito reservado no esquema HTTP, elas não precisam ter escape nos dados. A nota de § 2.3 sobre os caracteres reservados serem aqueles que mudam a semântica quando codificados por cento se aplica apenas em geral; os caracteres podem ser codificados por cento sem alterar a semântica para esquemas específicos e ainda assim ser reservados.
fonte
Para responder o que é válido em uma string de consulta, verifiquei quais caracteres especiais são substituídos por cromo ao fazer uma solicitação:
Nota: Isso provavelmente não significa que você não deve fazer escape de caracteres que não foram substituídos ao gerar URIs para links. Por exemplo, geralmente é recomendado não usar
~
em URIs devido a problemas de compatibilidade, mas ainda é um caractere válido.Outro exemplo seria o sinal de mais que é válido, mas geralmente tratado como um branco codificado quando um servidor o recebe como parte de uma solicitação. Portanto, ele deve ser codificado mesmo que seja válido quando seu propósito é representar um sinal de mais e não um espaço.
Portanto, para responder o que deve ser codificado: Caracteres inválidos e caracteres que você deseja tratar literalmente, mas têm um significado especial ou podem causar problemas no servidor.
fonte
/programming/2366260/whats-valid-and-whats-not-in-a-uri-query?param=b#1;c#2
um parâmetro de consulta válido?#
não pode aparecer dentro da parte da consulta de um URI como está. Você precisará codificá-lo como%23
, para que o URI seja/programming/2366260/whats-valid-and-whats-not-in-a-uri-query?param=b%231;c%232
.Apenas use
?q=1+2+3
Estou respondendo aqui a uma quarta pergunta :) que não perguntou, mas tudo começou com: como passo a lista de números a-la valores separados por vírgula? Parece-me que a melhor abordagem é apenas transmiti-los separados por espaço, para onde os espaços serão codificados em forma de url
+
. Funciona muito bem, contanto que você saiba que os valores na lista não contêm espaços (algo que os números tendem a não conter).fonte
+
faz ainda mais sentido no caso específico em que estou tentando usar uma vírgula.Sim. O
;
é reservado, mas não por um RFC. O contexto que define este componente é a definição doapplication/x-www-form-urlencoded
tipo de mídia, que faz parte do padrão HTML (seção 17.13.4.1 ). Em particular, a nota furtiva escondida na seção B.2.2 :Infelizmente, muitas estruturas de script do lado do servidor populares, incluindo ASP.NET, não oferecem suporte a esse uso.
fonte
?q=1;q=2;q=3
consulta seja válida, ela é ambígua: alguns frameworks do lado do servidor irão interpretar seu significado{ q: '1;q=2;q=3' }
, outros podem fazer isso de forma semelhante{ q: {'1', '2', '3'}}
.;
, o que significa que HTML4 e HTML5 são inconsistentes. Ugh, os perigos da linguagem não normativa em um documento de especificação ...{ q: 3 }
Gostaria de observar que também
page.html?q=1&q=2&q=3
é um URL válido. Esta é uma forma totalmente legítima de expressar uma matriz em uma string de consulta. A tecnologia do seu servidor determinará exatamente como isso é apresentado.No Classic ASP, você verifica
Response.QueryString("q").Count
e depois usaResponse.QueryString("q")(0)
(e (1) e (2)).Observe que você também viu isso em seu ASP.NET (acho que não era essa a intenção, mas veja):
Observe que o ponto-e-vírgula é ignorado, então você
a
definiu duas vezes e obteve seu valor duas vezes, separado por uma vírgula. Usar todos os e comerciaisDefault.aspx?a=1&a=2&b=1&a=3
resultaráa
em "1,2,3". Mas tenho certeza de que existe um método para obter cada elemento individual, caso os próprios elementos contenham vírgulas. É simplesmente a propriedade padrão da QueryString não indexada que concatena os subvalores junto com os separadores de vírgula.fonte
Eu tive o mesmo problema. O URL com hiperlink era um URL de terceiros e esperava uma lista de parâmetros
page.html?q=1,2,3
SOMENTE no formato e o URLpage.html?q=1%2C2%2C3
não funcionou. Consegui fazê-lo funcionar usando javascript. Pode não ser a melhor abordagem, mas pode verificar a solução aqui se ajudar alguém.fonte
Se você está enviando os caracteres ENCODED para o arquivo FLASH / SWF , então você deve ENCODE o caractere duas vezes !! (por causa do analisador Flash)
fonte