Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.142.250.114] |
|
Сообщ.
#1
,
|
|
|
Доброго времени суток! Разрабатываю приложение, которое общается с сервером по протоколу http. Все реализовано на Winhttp.
При отправке запроса GET или POST, не важно, где имеются только, английские символы, вопросов не возникает, все проходит. А тут понадобилось отправлять запросы, где есть русские символы, вот тут и проблема. Есть запрос вида: /lms/Do?name=Главная+страница&doaction=Go&id=0&type=StudentStartPage Если просматривать через Wireshark, то браузер отправляет запрос вида: /lms/Do?name=%D0%93%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F+%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&doaction=Go&id=0&type=StudentStartPage Собственно и вопрос, как программно из первого получить второе??? Да, на MSDN по функции WinHttpOpenRequest() есть такой флаг WINHTTP_FLAG_ESCAPE_PERCENT, но что-то я не врубаюсь, как подставлять параметры в эту функцию с этим флагом.... |
Сообщ.
#2
,
|
|
|
Цитата Игорь98 @ по протоколу http Протокол работает только на строках с 7 байтными символами. Для передачи других данных (двоичных, или, кириллических символов, может даже, юникод и т.д.) используют два распространённых подхода: 1. Передача 16-ричного кода символа (ASCII) с префиксом % 2. Передача данных в кодировке base64 Вы выбрали первый путь. Он достигается довольно просто, ваши символы представляются в HEX последовательности из двух байт, далее, последовательность переводится в строку, и к каждому элементу добавляется знак % слева. Реализовать можно через библиотеку (смотреть функции преобразования url), либо самописным велосипедом. Тут раз, тут два. |
Сообщ.
#3
,
|
|
|
Цитата Реализовать можно через библиотеку (смотреть функции преобразования url) А в самой библиотеке Winhttp, не предусмотрена ли определенная функция для таких действий? |
Сообщ.
#4
,
|
|
|
Цитата VisualProg @ 1. Передача 16-ричного кода символа (ASCII) с префиксом % utf8 там передается |
Сообщ.
#5
,
|
|
|
Цитата utf8 там передается Не пойму, где передается? У меня сейчас вот так, есть функция которая формирует запрос: BOOL WINAPI SDO_HTTP::MakeRequest_GET(TCHAR *sVerb) { BOOL bResult = FALSE; SDO_HTTP::hRequest = nullptr; SDO_HTTP::hRequest = WinHttpOpenRequest(SDO_HTTP::hConnect, _T("GET"), sVerb, nullptr, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_ESCAPE_PERCENT); if(SDO_HTTP::hRequest) { if(SDO_HTTP::bSetCookie) { WinHttpAddRequestHeaders(SDO_HTTP::hRequest, SDO_HTTP::sCookie, -1, 0x00); } WinHttpAddRequestHeaders(SDO_HTTP::hRequest, SDO_UPG_IN, -1, 0x00); WinHttpAddRequestHeaders(SDO_HTTP::hRequest, SDO_ACCEPT, -1, 0x00); WinHttpAddRequestHeaders(SDO_HTTP::hRequest, SDO_ACCEPT_EN, -1, 0x00); WinHttpAddRequestHeaders(SDO_HTTP::hRequest, SDO_ACCEPT_LN, -1, 0x00); bResult = TRUE; } else { SDO_HTTP::hRequest = nullptr; } return bResult; } В sVerb, я передаю "/lms/Do?s=%s&name=Главная+страница&doaction=Go&id=0&type=StudentStartPage" Но, что-то он в utf8 ничего не преобразовывает... На выходе вот такая хрень: GET /lms/Do?s=933MuHPS2MxvUqQkQ4Mc&name=..............+................&doaction=Go&id=0&type=StudentStartPage HTTP/1.1 |
Сообщ.
#6
,
|
|
|
Ну, есть ещё WinHttpCreateUrl().
Добавлено Цитата Игорь98 @ Заметь, русское "Главная+страница" в УРЛе должно быть правильно преобразовано компилятором в L"Главная+страница", если у тебя юникод. Обычно для этого достаточно, чтобы сырец был в CP1251, и компилятор это правильно понял. Именно компилятором, т.к. он преобразует строки твоего .cpp в строковые литералы TCHAR[]. В sVerb, я передаю "/lms/Do?s=%s&name=Главная+страница&doaction=Go&id=0&type=StudentStartPage" Но, что-то он в utf8 ничего не преобразовывает... |
Сообщ.
#7
,
|
|
|
Цитата shm @ utf8 там передается Есть куча условностей, хотя, в чистом виде, скорее всего можно передать UTF-8, но, в том же хидере, 100% не получится засунуть символы на вроде ":" в значение параметра/атрибута. Например, если в char попытаться впихнуть символ больший 7 битного, точно навернётся js-совский соккет. Хотя, опять же, возможно, требуется шаманить с указанием версии протокола http и зависит от браузера и версии js на нём. В случае с сервером - всё диктует непосредственно сервер. Там может быть полноценная 8 битная кодировка, но, это уже должен был нам рассказать автор вопроса. Я всего лишь привёл гарантированный способ передачи данных по хттп Добавлено Цитата Игорь98 @ А в самой библиотеке Winhttp, не предусмотрена ли определенная функция для таких действий? Я более чем уверен что предусмотрена. |
Сообщ.
#8
,
|
|
|
Нативной поддержки utf-8 в WinHTTP не будет.
Игорь98, что за траблы, понятия не имею. У меня работает: #include <windows.h> #include <winhttp.h> #include <iostream> #include <locale> #include <vector> #include <string> template <typename T, size_t N> constexpr size_t sizeOf(T (&arg)[N]) { using traits = std::char_traits<T>; return N - (arg[N-1] == traits::to_char_type(static_cast<traits::int_type>('\0'))); } int main() { URL_COMPONENTS urlComp; wchar_t urlStr[] = L"domain.рф/lms/Do?s=%s", urlExtra[]=L"&name=Главная+страница&doaction=Go&id=0&type=StudentStartPage"; DWORD urlLen = 0; std::wcout.imbue(std::locale("russian_russia.OCP")); ZeroMemory(&urlComp, sizeof(urlComp)); urlComp.dwStructSize = sizeof(urlComp); urlComp.nScheme = INTERNET_SCHEME_HTTP; urlComp.lpszHostName = urlStr; urlComp.lpszExtraInfo = urlExtra; urlComp.dwHostNameLength = sizeOf(urlStr); urlComp.dwExtraInfoLength = sizeOf(urlExtra); WinHttpCreateUrl( &urlComp, ICU_ESCAPE, NULL, &urlLen); std::vector<wchar_t> newUrl(urlLen); if (!WinHttpCreateUrl( &urlComp, ICU_ESCAPE, &newUrl.front(), &urlLen)) std::wcerr << L"WinHttpCreateUrl(): error is " << GetLastError() << std::endl; else std::wcout << L"Old URL: " << L"http://" + std::wstring(urlStr) + urlExtra << "\nNew URL: " << &newUrl.front() << std::endl; } |