Characters allowed in a URL

Viewed 308021

Does anyone know the full list of characters that can be used within a GET without being encoded? At the moment I am using A-Z a-z and 0-9... but I am looking to find out the full list.

I am also interested into if there is a specification released for the up coming addition of Chinese, Arabic url's (as obviously that will have a big impact on my question)

10 Answers

This answer discusses characters may be included inside a URL fragment part without being escaped. I'm posting a separate answer since this part is slightly different than (and can be used in conjunction with) other excellent answers here.

The fragment part is not sent to the server and it is the characters that go after # in this example:

https://example.com/#STUFF-HERE

Specification

The relevant specifications in RFC 3986 are:

  fragment    = *( pchar / "/" / "?" )
  pchar       = unreserved / pct-encoded / sub-delims / ":" / "@"
  unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
  sub-delims  = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

This also references rules in RFC 2234

  ALPHA       =  %x41-5A / %x61-7A   ; A-Z / a-z
  DIGIT       =  %x30-39             ; 0-9

Result

So the full list, excluding escapes (pct-encoded) are:

A-Z a-z 0-9 - . _ ~ ! $ & ' ( ) * + , ; = : @ / ?

For your convenience here is a PCRE expression that matches a valid, unescaped fragment:

/^[A-Za-z0-9\-._~!$&'()*+,;=:@\/?]*$/

Encoding

Counting this up, there are:

26 + 26 + 10 + 19 = 81 code points

You could use base 81 to efficiently encode data here.

If you like to give a special kind of experience to the users you could use pushState to bring a wide range of characters to the browser's url:

enter image description here

var u="";var tt=168;
for(var i=0; i< 250;i++){
 var x = i+250*tt;
console.log(x);
 var c = String.fromCharCode(x);
 u+=c; 
}
history.pushState({},"",250*tt+u);
Related