Kodowanie tekstu -> "URLEncode"

dział ogólny

Re: Kodowanie tekstu -> "URLEncode"

Nowy postprzez Cyfrowy Baron » czwartek, 25 lutego 2010, 21:52

Sam natrafiłem na przypadek gdy funkcja nie zadziała. można to oczywiście poprawić:

Kod: Zaznacz cały
string url_encode(const String sUrl)
{
int p = sUrl.AnsiPos("&q=");
string s1, s2;
string baseUrl;
if(p > 0 || sUrl.SubString(1, 4).LowerCase() != "http")
{
  baseUrl = (sUrl.SubString(1, p + 2)).c_str();
  s1   = (sUrl.SubString(p + 3, sUrl.Length())).c_str();

  char tmp[] = "%XX";

  for(string::const_iterator i = s1.begin(); i != s1.end(); ++i)
  {

        if((*i < 'a' || *i > 'z') && (*i < 'A' || *i > 'Z') &&
          (*i < '0' || *i > '9') && !strchr("-_", *i))
        {
                sprintf(tmp + 1,"%02X",(unsigned char)*i);
            s2 += tmp;
        }
        else s2 += *i;
  }
}
else return sUrl.c_str();

return baseUrl + s2;
}


ale to takie ciągłe łatanie funkcji.
Musiałbym to spokojnie przemyśleć i znaleźć jakieś uniwersalne rozwiązanie. Funkcja z INDY działa niezależnie od tego czy jest to cały adres czy tylko zapytanie, więc jest to do zrobienia.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Kodowanie tekstu -> "URLEncode"

Nowy postprzez polymorphism » czwartek, 25 lutego 2010, 22:16

Nie rozumiem co chciałeś mi tym kodem udowodnić.

To chciałem udowodnić, że jeśli zamiast CP1250 będzie coś innego, coś wymagającego zakodowania, to twoja funkcja nie zadziała. Przyjąłeś bardzo naiwne założenie, że "&q=" zawsze wystąpi jako pierwsze, a nikt tego nie powiedział. Ba! nawet to q nie musi wystąpić.

Czasami ma znaczenie. Wysyłając np. zapytanie do wyszukiwarki filmweb.pl z hasłem: gość (...)

No dobra, ale to nie wina funkcji, tylko złego kodowania, którego użyłeś do komunikacji z serwerem filmweb'u. Daj jej gość w utf-8 i wszystko będzie jak trzeba.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Kodowanie tekstu -> "URLEncode"

Nowy postprzez polymorphism » czwartek, 25 lutego 2010, 22:40

Funkcja z INDY działa niezależnie od tego czy jest to cały adres czy tylko zapytanie, więc jest to do zrobienia.

Oczywiście, że jest, tylko trzeba by dokonać analizy URL-a, nawet nie musiałaby być zbyt wnikliwa. Choć według mnie jest to zbyteczne, bo na ogół składasz URL-e z gotowych elementów i wiesz, które elementy musisz zakodować - przykład z google dobrze to pokazuje.


p.s. a jak INDY daje sobie radę w teście z ampersandem, czyli:

http://www.google.com/search?q=&&ie=CP1250


:?:
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Kodowanie tekstu -> "URLEncode"

Nowy postprzez Cyfrowy Baron » piątek, 26 lutego 2010, 10:17

p.s. a jak INDY daje sobie radę w teście z ampersandem, czyli:


Nie tłumaczy tego adresu, ale z tym adresem wklejonym w pasek adresu to nawet przeglądarka Firefox sobie nie radzi, gdyż tłumaczy go na:


http://www.google.com/webhp?ie=CP1250



Jak widać brak kodowania w UTF-8 sprawia, że nie można wysłać zapytania ze znakami && gdyż są zastępowane znakiem zastępczym. Nawet w C++Builder 2010 INDY nie tłumaczy tych znaków na %26, co więcej odkryłem, że funkcja URLEncode musi zawierał cały adres, gdyż przy samym zapytaniu wyskakuje błąd. Właściwie to z nazwy funkcji powinienem wywnioskować, że służy ona do enkodowania całych adresów. Istnieje jednak inna funkcja ParamsEncode:

Kod: Zaznacz cały
// kod dla C++Builder 2010
#include <IdURI.hpp>
void __fastcall TForm1::Button3Click(TObject *Sender)
{

String Url = "http://www.google.com/search?q=&&ie=CP1250";

TIdURI *idUrl = new TIdURI("");

Edit1->Text = idUrl->ParamsEncode(Url); /* dla C++Builder poniżej wersji 2010:  idUrl->ParamsEncode(__classid(TIdURI), Url); */
delete idUrl;
}
//---------------------------------------------------------------------------


Tłumacząca zarówno całe adresy jak i tylko same zapytania, ale i ta funkcja nie tłumaczy znaków zarezerwowanych, czyli: "-_;/?:@=&.". To ograniczenie w enkodowaniu może być czasami przeszkodą.

Idealnym rozwiązaniem była by wiec funkcja, która potrafiłaby oddzielić adres URL od zapytania. W mojej modyfikacji za punkt podziału przyjąłem &p=, ale trzeba by zawrzeć w niej wszystkie możliwe punkty podziału. Modyfikacja przewiduje wystąpienie na początku łańcucha znaków frazy http, może jednak wystąpić sytuacja, gdy pojawi się adres bez tego przedrostka z całym adresem bez zapytania, lub z zapytaniem, funkcja zadziała prawidłowo.



Jak w string zastąpić funkcje AnsiPos i SubString, bez dokonywania konwersji typu string na AnsiString czy też UnicodeString?
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Kodowanie tekstu -> "URLEncode"

Nowy postprzez polymorphism » sobota, 27 lutego 2010, 23:32

---- Z małym opóźnieniem, bo nie dostałem powiadomienia... dziwne :| ----

Nie tłumaczy tego adresu (...)

Ha, no widzisz. Funkcje do wszystkiego zawsze mają słabe punkty.

Jak widać brak kodowania w UTF-8 sprawia, że nie można wysłać zapytania ze znakami && gdyż są zastępowane znakiem zastępczym.
Kodowanie UTF-8 nie ma tu żadnego znaczenia, bo dwa ampersandy w tym kodowaniu to takie same dwa ampersandy jak w kodowaniu ASCII - ten znak nie podlega konwersji ascii -> unikod.

(...) ale z tym adresem wklejonym w pasek adresu to nawet przeglądarka Firefox sobie nie radzi

No nie radzi, bo podobnie jak INDY ma problem z tym znakiem - traktuje go jako separator, a nie jako wartość. I właśnie po to jest to kodowanie, żeby nie było tych niejednoznaczności.

W mojej modyfikacji za punkt podziału przyjąłem &p=, ale trzeba by zawrzeć w niej wszystkie możliwe punkty podziału.

Wszystkie możliwe?! Jest ich nieskończenie wiele, bo p to tylko nazwa, a ta może być dowolnie długim ciągiem znakowym. Zamiast kombinować na ślepo, zajrzyj do specyfikacji, przeczytaj jak skonstruowany jest adres URL, z jakich elementów się składa.

W każdym razie, co byś nie wymyślił, problemu znaku & łatwo nie ominiesz.

Jak w string zastąpić funkcje AnsiPos i SubString (...)

A dokumentacja od czego jest? ;) find_first_of i substr/assign.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Poprzednia strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 9 gości

cron