Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uncaught URIError: URI malformed - jquery UI tabs on Windows

I'm using jquery UI tabs in a local Windows development environment. I'm testing with their demo code

<div id="tabs">
  <ul>
    <li><a href="#tabs-1">Nunc tincidunt</a></li>
    <li><a href="#tabs-2">Proin dolor</a></li>
    <li><a href="#tabs-3">Aenean lacinia</a></li>
  </ul>
  <div id="tabs-1">
    <p>Proin elit arcu, rutrum commodo, vehicula tempus, commodo a, risus. Curabitur nec arcu. </p>
  </div>
  <div id="tabs-2">
    <p>Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie</p>
  </div>
  <div id="tabs-3">
    <p>Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede ve</p>

  </div>
</div>

The problem is that I'm getting a "Uncaught URIError: URI malformed" on this function:

function isLocal( anchor ) {
    return anchor.hash.length > 1 &&
        decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
Uncaught URIError: URI malformed
            decodeURIComponent( location.href.replace( rhash, "" ) );
} 

I suspect this is due to the URI on windows environment that looks like this:

file:///C:/Work/my%20project/yadda%20ac%E7%F5es%20yadda/submenu.html#tabs-1

How can I have it working on local Windows, since my clients will want to see it working there before going live? I've tested and I know this is being caused by the encoding of the special characters on the uri (like on the word "acções"). Is there a way to have it working even with special characters?

I know I can fix this simply by removing these characters and renaming the file/folder, but I'd like to have a solution that is more client proof in case they decide to rename the folders again (and everything just goes CABOOM on their faces).

like image 205
Catarina Lou Avatar asked Mar 10 '13 19:03

Catarina Lou


3 Answers

This is a consequence of the decodeURIComponent method, which assumes that the given string's percent encoded bytes are in UTF-8 (see step 4.d.vii.8 of the Decode operation in sec. 15.1.3 of ECMAScript). Your example string:

"file:///C:/Work/my%20project/yadda%20ac%E7%F5es%20yadda/submenu.html#tabs-1"

Contains the percent-decoded bytes 0xE7 0xF5, which can't occur one after the other in a valid UTF-8 string (they represent the two characters çõ in Windows-1252). Accordingly, decodeURIComponent throws a URIError exception.

One way to solve this, which I haven't tested yet, is to ensure that your Web page is served using the UTF-8 character encoding, rather than ISO-8859-1, which I presume is the default.

To do this, include a META tag as follows:

<meta http-equiv="Content-Type" content="text/html;charset=utf-8">

(While the ideal thing is to include a Content-Type header containing the charset, this is not generally possible in local testing involving the file system.)

And also ensure that the Web pages themselves are encoded in UTF-8.


Also, where does your example string appear on your Web pages? How is it generated? What browser did you test the behavior on? The answer will help me tell you what to do.

like image 55
Peter O. Avatar answered Oct 23 '22 13:10

Peter O.


This is a bug in jquery - http://bugs.jqueryui.com/ticket/9518 - present for non-UTF8 URLs. I had the same problem and solved it. As I couldn't change the encoding of my page to UTF-8, I finally patched my jqueryui and used Rainer Plumer's solution as a workaround, but I had to use it twice because I have some URI parameters which contain encoded URIs. So my solution was

decodeURIComponent( unescape( unescape(s)) )

More generally, there should probably be repeat-until loop, unescaping until you keep getting the same result. This workaround is not a clean solution for sure. The clean solution is asked here:

Submit form with get method in non UTF-8 encoding

PS: the entire patch of jquery UI:

function isLocal( anchor ) {
        return anchor.hash.length > 1 && 
                decodeURIComponent( unescape( unescape( anchor.href.replace( rhash, "" ) ) ) ) ===
                        decodeURIComponent( unescape( unescape( location.href.replace( rhash, "" ) ) ) );
}
like image 7
Tomas Avatar answered Oct 23 '22 13:10

Tomas


Something like this ?

s = "file:///C:/Work/my%20project/yadda%20ac%E7%F5es%20yadda/submenu.html#tabs-1";
decodeURIComponent( unescape(s) )
like image 4
Rainer Plumer Avatar answered Oct 23 '22 15:10

Rainer Plumer