However, the JS gettters are all over the place...<p>Given this:<p><pre><code>    a = document.createElement(&#x27;a&#x27;)
    a.href = &quot;&#x2F;ö&#x2F;o?ö&#x2F;o#ö&#x2F;o&quot;
    console.log(a.hash, a.pathname, a.search)
</code></pre>
we get:<p><pre><code>    Browser  .hash       .pathname   .search 
 
    Chrome   #ö&#x2F;o        &#x2F;%C3%B6&#x2F;o   ?%C3%B6&#x2F;o  
    Firefox  #%C3%B6&#x2F;o   &#x2F;%C3%B6&#x2F;o   ?%C3%B6&#x2F;o  
    Safari   #%C3%B6&#x2F;o   &#x2F;%C3%B6&#x2F;o   ?%C3%B6&#x2F;o  
    Edge     #ö&#x2F;o        &#x2F;ö&#x2F;o        ?ö&#x2F;o  
    IE11     #ö&#x2F;o        ö&#x2F;o (ouch)  ?ö&#x2F;o  
</code></pre>
Likewise for domains, some UAs return them Punycoded (but don&#x27;t provide a decoder), some in Unicode, and PhantomJS passes it percent encoded...<p>It&#x27;s a big mess.<p>I discovered this while working on a SPA router that can handle routes in either `pathname`, `search` or `hash` mode... The routes are defined as the keys of a JS object, in Unicode in the source, and we have to juggle back and forth to match what `document.location.*` returns.