Spacja html jest wyświetlana jako% 2520 zamiast% 20

110

Przekazanie nazwy pliku do przeglądarki Firefox powoduje zamianę spacji na %2520 zamiast %20.

Mam następujący kod HTML w pliku o nazwie myhtml.html:

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

Kiedy myhtml.htmlładuję do Firefoksa, obraz jest uszkodzony. Więc klikam prawym przyciskiem myszy link, aby wyświetlić zdjęcie i pokazuje ten zmodyfikowany adres URL:

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

Co za cholera? Zmieniło moją przestrzeń w %2520. Czy nie powinno to być konwersją do formatu %20?

Jak zmienić ten plik HTML, aby przeglądarka mogła znaleźć mój obraz? Co tu się dzieje?

Eric Leschinski
źródło

Odpowiedzi:

219

Trochę wyjaśnienia, co to %2520jest:

Wspólny znak spacji jest kodowany tak, %20jak sam zauważyłeś. %Znak jest zakodowany jako %25.

Sposób, w jaki się %2520to, gdy adres URL ma już %20w nim, i dostaje urlencoded znowu, który przekształca %20się %2520.

Czy jesteś (lub jakikolwiek framework, którego możesz używać) podwójne kodowanie znaków?

Edycja: Rozwijam nieco ten temat, szczególnie dla linków LOKALNYCH . Zakładając, że chcesz połączyć się z zasobem C:\my path\my file.html:

  • jeśli podasz tylko lokalną ścieżkę do pliku, przeglądarka powinna zakodować i zabezpieczyć wszystkie podane znaki (w powyższym, powinieneś nadać mu spacje, jak pokazano, ponieważ %jest to prawidłowy znak nazwy pliku i jako taki zostanie zakodowany) podczas konwersji do właściwego adresu URL (patrz następny punkt).
  • jeśli podasz adres URL z file://protokołem, w zasadzie stwierdzasz, że podjąłeś wszelkie środki ostrożności i zakodowałeś to, co wymaga zakodowania, resztę należy traktować jako znaki specjalne. W powyższym przykładzie powinieneś więc podać file:///c:/my%20path/my%20file.html. Oprócz poprawiania ukośników klienci nie powinni tutaj kodować znaków.

UWAGI:

  • Kierunek ukośnika /- w adresach URL używane są ukośniki w przód , \w ścieżkach systemu Windows w odwrotne ukośniki , ale większość klientów będzie współpracować z obydwoma, konwertując je na właściwy ukośnik.
  • Ponadto po nazwie protokołu znajdują się 3 ukośniki, ponieważ po cichu odnosisz się do bieżącej maszyny zamiast do zdalnego hosta (pełna ścieżka nieskrócona byłaby file://localhost/c:/my%20path/my%file.html), ale znowu większość klientów będzie działać bez części hosta (tj. Tylko dwa ukośniki ) zakładając, że masz na myśli maszynę lokalną i dodając trzeci ukośnik.
Nick Andriopoulos
źródło
1
Hexblot ma tu właściwie rację. Zwykle dzieje się tak, gdy ponownie kodujesz swoje adresy URL przez programowanie, a bot przychodzi i koduje go po raz drugi. Roboty mają zły nawyk. Są dwa przypadki, w których możesz sobie poradzić z tym problemem. 1) Możesz 404 lub 401 z wyjątkiem try catch lub możesz napisać małą funkcję, która zdekoduje podwójnie zdekodowane wartości przed przekazaniem jej innej metodzie logiki biznesowej.
Ryan Watts
Pomogło mi to zrozumieć, dlaczego otrzymałem to podczas wysyłania żądania jQuery ajax. Ustawiałem atrybut danych w żądaniu Ajax GET z funkcją encodeURIComponent na wartość, ale jQuery już to robi domyślnie, stąd dlaczego otrzymałem% 2520. Bardzo pomocne dzięki.
Asher
Czy nie ma argumentu wiersza poleceń dla chrome, który mówi mu, czy interpretuje, czy nie interpretuje łącza?
AleX_
Mam http://mysite/test & that... If I use UrlEncode`, na które się zmienia, http://mysite/test%20&%20thatale chcę również &zmienić na% 26, więc jest to mysite / test% 20% 26% 20that `Jak mogę to zrobić?
Si8
10

Z jakiegoś - być może ważnego - powodu adres URL został zakodowany dwukrotnie. %25jest %znakiem urlencoded . Tak więc oryginalny adres URL wyglądał następująco:

http://server.com/my path/

Potem został raz zakodowany jako urlenkod:

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

i dwukrotnie:

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

Nie powinieneś więc robić urlencoding - w twoim przypadku - ponieważ wydaje się, że inne komponenty już to robią . Użyj po prostu spacji

hek2mgl
źródło
Mam ten sam problem, ale nie rozumiem, dlaczego domyślne kodowanie urlen zostało przetworzone dwukrotnie za pierwszym razem.
jungwon jin
W zależności od sytuacji podwójne kodowanie może być całkowicie poprawnym wynikiem prawidłowego użycia kodowania. Ta odpowiedź może sprawiać wrażenie, że podwójne kodowanie jest zawsze błędne i że można po prostu rozwiązać problemy z kodowaniem, dodając tyle wywołań kodowania / dekodowania, ile potrzeba, aby „sprawić, by działało”. To jest złe i właśnie w ten sposób pojawiają się błędy w kodowaniu. -1
Florian Winter,
@FlorianWinter Naprawdę nie widzę, gdzie czytasz to między wierszami. Czy możesz mi pomóc? (Proszę przeczytać pytanie i moją odpowiedź)
hek2mgl
7

Kiedy próbujesz odwiedzić lokalną nazwę pliku przez przeglądarkę Firefox, musisz wymusić file:\\\protokół ( http://en.wikipedia.org/wiki/File_URI_scheme ), w przeciwnym razie firefox zakoduje Twoje miejsce DWUKROTNIE. Zmień fragment kodu HTML z tego:

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

do tego:

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

albo to:

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

Następnie firefox jest powiadamiany, że jest to lokalna nazwa pliku i poprawnie renderuje obraz w przeglądarce, poprawnie kodując ciąg.

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

Eric Leschinski
źródło
0

Poniższy fragment kodu rozwiązał mój problem. Pomyślałem, że to może być przydatne dla innych.

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

Raczej używam default, encodeURIComponentmoja pierwsza linia kodu konwertuje wszystko spacesna hyphensużycie wzorca regex, /\s\ga następna linia po prostu odwraca, tj. Konwertuje wszystko z hyphenspowrotem na spacesużycie innego regex pattern /-/g. Tutaj /gjest faktycznie odpowiedzialny za finding alldopasowywanie znaków.

Kiedy wysyłam tę wartość do mojego wywołania Ajax, przechodzi ona jako normal spaceslub po prostu %20iw ten sposób się pozbywa double-encoding.

Subrata Sarkar
źródło
1
Zakładam, że nie rozwiązujesz sprawy, po prostu ją ukrywasz - główna przyczyna wciąż jest gdzieś tam, a ty wykonujesz podwójną pracę (gdzieś przypadkowo kodujesz dwa razy, a gdzie indziej dekodujesz ręcznie, aby pokryć to w górę). Zakładając, że chcesz zrobić coś „poprawnie”, najlepiej byłoby przeprowadzić debugowanie i znaleźć prawdziwego winowajcę.
Nick Andriopoulos
Właściwie rozwiązanie działało dla mnie wszędzie tam, gdzie mam ten problem. Więc wysłałem.
Subrata Sarkar
2
@NiladriSarkar To, co hexbolt próbował powiedzieć, to to, że chociaż twój kod działa, nie jest to realne rozwiązanie, raczej brudna poprawka i należy jej unikać ...
Zobacz
-1

Spróbuj tego?

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

Mam nadzieję
źródło
1
Witamy w StackOverflow! Ogólnie odpowiedzi są bardziej przydatne, jeśli zawierają wyjaśnienie, dlaczego Twoja sugestia rozwiąże problem PO, a nie tylko fragment kodu. Ponieważ na to pytanie jest już zaakceptowana odpowiedź, dobrym pomysłem byłoby dodanie wyjaśnienia, dlaczego twoja odpowiedź jest bardziej poprawna niż ta.
DaveyDaveDave