According to this question, many characters (#, <, >, [, ], {, }, ...) should be forbidden in URL fragments (that is, the part of an URL after the #). But a test script I wrote seems to indicate that most current browsers allow some of these characters:
const unsupported = [];
for (let charCode = 32; charCode < 127; charCode++) {
const c = String.fromCharCode(charCode);
window.location = `#${c}`;
const afterRoundtrip = window.location.href.match(/#(.*)/)[1];
const characterIsSupported = afterRoundtrip === c;
if (!characterIsSupported) {
unsupported.push(c);
}
}
console.log('Unsupported: ', unsupported);
This script iterates over all printable ASCII characters, tries to append each to the URL after a hash, reads it back, and outputs the characters that the browser didn't allow.
On Chrome, the output was [" ", """, "<", ">", "`"]
; on both Safari and Edge, it was [" "]
. So it seems that almost all ASCII characters are allowed within URL fragments.
I'm confused: Should browsers allow all these special characters in URL fragments? If so, can I rely on this behavior and use these characters for single-page applications? Is there some standard I'm not aware of?