146

Passing a filename to the firefox browser causes it to replace spaces with %2520 instead of %20.

I have the following HTML in a file called myhtml.html:

<img src="C:\Documents and Settings\screenshots\Image01.png"/>

When I load myhtml.html into firefox, the image shows up as a broken image. So I right click the link to view the picture and it shows this modified URL:

file:///c:/Documents%2520and%2520Settings/screenshots/Image01.png
                    ^
                    ^-----Firefox changed my space to %2520.

What the heck? It converted my space into a %2520. Shouldn't it be converting it to a %20?

How do I change this HTML file so that the browser can find my image? What's going on here?

Toby Allen
  • 10,997
  • 11
  • 73
  • 124
Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335

6 Answers6

287

A bit of explaining as to what that %2520 is :

The common space character is encoded as %20 as you noted yourself. The % character is encoded as %25.

The way you get %2520 is when your url already has a %20 in it, and gets urlencoded again, which transforms the %20 to %2520.

Are you (or any framework you might be using) double encoding characters?

Edit: Expanding a bit on this, especially for LOCAL links. Assuming you want to link to the resource C:\my path\my file.html:

  • if you provide a local file path only, the browser is expected to encode and protect all characters given (in the above, you should give it with spaces as shown, since % is a valid filename character and as such it will be encoded) when converting to a proper URL (see next point).
  • if you provide a URL with the file:// protocol, you are basically stating that you have taken all precautions and encoded what needs encoding, the rest should be treated as special characters. In the above example, you should thus provide file:///c:/my%20path/my%20file.html. Aside from fixing slashes, clients should not encode characters here.

NOTES:

  • Slash direction - forward slashes / are used in URLs, reverse slashes \ in Windows paths, but most clients will work with both by converting them to the proper forward slash.
  • In addition, there are 3 slashes after the protocol name, since you are silently referring to the current machine instead of a remote host ( the full unabbreviated path would be file://localhost/c:/my%20path/my%file.html ), but again most clients will work without the host part (ie two slashes only) by assuming you mean the local machine and adding the third slash.
Nick Andriopoulos
  • 10,313
  • 6
  • 32
  • 56
  • 1
    Hexblot is actually correct here. Usually this happens when youa re url encoding your urls by programming , and a bot comes in and encodes it a second time. Bots have a bad habit of doing this. There are two was you can handle this issue. 1) You can either 404 or 401 with a try catch exception or you can write a small function that will decode the double decoded values before you hand it off to another method for business logic. – Ryan Watts Sep 09 '14 at 16:42
  • This helped me figure out why I was getting it when sending a jQuery ajax request. I was setting the data attribute in an ajax GET request with the encodeURIComponent function on the value, but jQuery already does it by default, hence why i was getting %2520. Really helpful thanks. – Asher Aug 24 '16 at 10:23
  • Isn't there a command line argument for chrome to tell it either interpret or don't interpret the link? – AleX_ Mar 14 '17 at 17:55
  • I have `http://mysite/test & that... If I use `UrlEncode` it changes to `http://mysite/test%20&%20that` but I also want the `&` to change to %26 as well so it's http://mysite/test%20%26%20that` How can I do that? – Si8 Apr 04 '17 at 18:39
  • 1
    Another scenario where this can happen is if you have files with filenames containing `%20` (common if they were saved from a browser and it can happen when writing scripts to crawl websites too) and you then serve them via a web server like apache. In such circumstances you will actually need to refer to them in URL's with the second level of encoding. You can prevent this by url-decoding the filenames while saving them, or doing it in a batch after the fact. – cazort Jun 30 '21 at 16:51
20

For some - possibly valid - reason the url was encoded twice. %25 is the urlencoded % sign. So the original url looked like:

http://server.com/my path/

Then it got urlencoded once:

http://server.com/my%20path/

and twice:

http://server.com/my%2520path/

So you should do no urlencoding - in your case - as other components seems to to that already for you. Use simply a space

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • I got same issue but I don't understand why default urlencoding was processed twice at the first time. – kakadais Feb 10 '17 at 06:39
  • Depending on the situation, double-encoding may be a perfectly valid result of using encoding correctly. This answer may create the impression that double-encoding is always wrong, and that you can simply fix encoding problems by adding as many encode/unencode calls as necessary to "make it work". This is wrong, and this is how encoding bugs come to be in the first place. -1 – Florian Winter Dec 11 '18 at 15:19
  • @FlorianWinter I don't really see where you read this between the lines. Can you help me out? (Please read the question and my answer) – hek2mgl Dec 11 '18 at 16:37
8

When you are trying to visit a local filename through firefox browser, you have to force the file:\\\ protocol (http://en.wikipedia.org/wiki/File_URI_scheme) or else firefox will encode your space TWICE. Change the html snippet from this:

<img src="C:\Documents and Settings\screenshots\Image01.png"/>

to this:

<img src="file:\\\C:\Documents and Settings\screenshots\Image01.png"/>

or this:

<img src="file://C:\Documents and Settings\screenshots\Image01.png"/>

Then firefox is notified that this is a local filename, and it renders the image correctly in the browser, correctly encoding the string once.

Helpful link: http://support.mozilla.org/en-US/questions/900466

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
2

Try using this

file:///c:/Documents%20and%20Settings/screenshots/Image01.png

Whenever you are trying to open a local file in the browser using cmd or any html tag use "file:///" and replace spaces with %20 (url encoding of space)

Vishnu
  • 21
  • 4
0

The following code snippet resolved my issue. Thought this might be useful to others.

var strEnc = this.$.txtSearch.value.replace(/\s/g, "-");
strEnc = strEnc.replace(/-/g, " ");

Rather using default encodeURIComponent my first line of code is converting all spaces into hyphens using regex pattern /\s\g and the following line just does the reverse, i.e. converts all hyphens back to spaces using another regex pattern /-/g. Here /g is actually responsible for finding all matching characters.

When I am sending this value to my Ajax call, it traverses as normal spaces or simply %20 and thus gets rid of double-encoding.

Subrata Sarkar
  • 2,975
  • 6
  • 45
  • 85
  • 1
    I assume because you are not solving the matter, just covering it up - the root cause it still somewhere there, and you're doing double work ( somewhere you are accidentally encoding twice, and somewhere else you're decoding manually in order to cover it up ). Assuming you want to do things "properly", the best thing would be to debug and find the real culprit. – Nick Andriopoulos Jan 26 '16 at 09:05
  • Actually the solution worked for me wherever I got this issue. So I posted. – Subrata Sarkar Jan 27 '16 at 04:39
  • 2
    @NiladriSarkar what hexbolt was trying to say is that while your code works, it is not a viable solution, rather a dirty fix, and should be avoided... – 2Dee Oct 12 '16 at 14:09
  • Is it a dirty fix or just a fix? When you're using a framework that does not check for double encoding (like NSURL ...), implementing your own encoding could also be called a sanity-saver. – Elise van Looij Jan 11 '21 at 14:13
  • Actually, NSURL's absoluteString does expose one to the problem of double encoding, but NSURL's path does not. – Elise van Looij Jan 14 '21 at 21:08
-1

Try this?

encodeURIComponent('space word').replace(/%20/g,'+')

Hopefulee
  • 136
  • 2
  • 3
  • 1
    Welcome to StackOverflow! Generally answers are more useful if they include some explanation about why your suggestion will solve the problem of the OP, rather than just a code snippet. Also, as this question already has an accepted answer, it would be a good idea to add some explanation as to why your answer is more correct than that one. – DaveyDaveDave May 10 '18 at 05:37