Firefox (but not Chrome) messes-up the location.hash result:
https://jsfiddle.net/nsoaee4q/14/
What workaround works for all valid fragment values?
Not this, note:
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<script>
"use strict";
location.hash = "'%97";
console.log(location.hash);
// Expected: #'%97
// SUCCESS on Chrome
// FAIL on Firefox: #%27%97
// Attempted fix
console.log('#'+decodeURIComponent(location.href.split("#")[1] || ""));
// FAIL 'Uncaught URIError: URI malformed'
</script>
Note: This is not a duplicate of Encoding of window.location.hash and that question's accepted answer's solution is faulty.
UPDATE: The above example's %97 is claimed in comments to be invalid. Here's an example that avoids that issue:
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<script>
"use strict";
location.hash = "%20'";
console.log(location.hash);
// Expected: #%20'
// SUCCESS on Chrome
// FAIL on Firefox: #%20%27
// Attempted fix
console.log('#'+decodeURIComponent(location.href.split("#")[1] || ""));
// FAIL: # '
</script>
Note: Title was previously: "How can I workaround Firefox's bugged location.hash read?", changed for clarification.
Note: Kaiido's answer below of 2017-01-10 doesn't meet the requirement to work for all valid hash values, but does meet a less strict requirement, as explained in its comments.
Note: This bug report is related https://bugzilla.mozilla.org/show_bug.cgi?id=1329960 , pic https://i.stack.imgur.com/uvLLX.png