 Отправка POST запроса
    , Есть образец, надо переделать
    Отправка POST запроса
    , Есть образец, надо переделать
  |  | Наши проекты: Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту | |
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS | 
| [216.73.216.107] | 
|   | 
 | 
 Отправка POST запроса
    , Есть образец, надо переделать
    Отправка POST запроса
    , Есть образец, надо переделать
  | 
         
         
          
           Сообщ.
           #1
          
          , 
          
         
         | |
|  |  Доброго времени суток! Поскольку в данной теме нуб, то задам глупый вопрос (и не один  ), не пинайте сильно.  Предыстория такова: Вот в этой инструкции (API одноклассники) есть пример HTML-кода (укорочу его с трех до одного файла, для простоты и добавлю реальный <upload URL>):   Следующий фрагмент HTML-кода можно использовать для добавления ... изображений: <form method="POST" enctype="multipart/form-data" action="https://gup.mycdn.me/uploadImage?apiToken=aciB5aM%2FxsI4WkCnuN4RFAczLBxVBX2mkYUhngQh7efNbHN7YzG5rWPOy7Ww%2BEblzo1db%2FegAC50yepo3agiKsudaYwrL7xfYbaA8ydctS7WNO2butBhsw%3D%3D&photoIds=Ba9z4BfOlNoTe6%2FVJyahKlpqGliqCyVrUdEynq628FB6IVP%2FRwvqVQ%3D%3D">   <input type="file" name="pic1" accept="image/*" />   <input type="submit" /> </form> Если его банально сохранить в файл htm и открыть его в браузере, то видим кнопку "Обзор" для выбора файлов и кнопку "Отправить запрос". Забегая вперед скажу, что тут все работает замечательно, файл отправляются на сервер и мне показывается правильный ответ. В той же инструкции представлен образец POST-запроса, который будет отправлен на <upload URL> после выбора файлов изображений по кнопке "Обзор" и нажатия кнопки "Отправить Запрос". Вот он: Цитата  HTTP POST request URL : <upload URL> Post: Content-Type: multipart/form-data; boundary=---------------------------11020459624021 Content-Length: 831083 \\ -----------------------------11020459624021 Content-Disposition: form-data; name="pic1"; filename="IMG_0699.JPG" Content-Type: image/jpeg .................... -----------------------------11020459624021-- Свой реальный запрос почему-то посмотреть не получается (пробовал HttpAnalyzer, но, наверное, руки кривые). Теперь, собственно, вопрос: Пытаюсь этот запрос послать программно. Использую HttpOpenRequest + HttpSendRequest (пишу на С++, MFC). В lpOptional кладу следующий текст: Цитата  Content-Type: multipart/form-data; boundary=---------------------------11020459624021 Content-Length: 831083 \\ -----------------------------11020459624021 Content-Disposition: form-data; name="pic1"; filename="d:\MyVC++\~BackupOK\1.JPG" Content-Type: image/jpeg .................... -----------------------------11020459624021-- И в ответ получаю сообщение: Цитата  {"error_msg":"one.image.server.upload.ContentUploadServerException: NO_IMAGE","error_code":"505","error_data":"NO_IMAGE"} Похоже, что неправильно формирую запрос... Тут как минимум два вопроса: 1. Content-Length: 831083 - это надо каким-то образом вычислять? 2. filename="d:\MyVC++\~BackupOK\1.JPG" - тут должен быть путь к моему локальному файлу? С уважением! | 
| 
         
         
          
           Сообщ.
           #2
          
          , 
          
         
         | |
|  |  На всякий случай приведу программный код:       HINTERNET hInetSession;     std::string strURL = "";     std::string strStop = "";     char cBuf[200001];     DWORD dwRead;     int dwReaded = 0;     hInetSession = InternetOpen( "Opera/9.51 (Windows NT; U; ru)", INTERNET_OPEN_TYPE_PRECONFIG, NULL, 0, 0);     if(!hInetSession)     {         AfxMessageBox("---2");         return;     }     HINTERNET hConnect = InternetConnect(hInetSession, "gup.mycdn.me", INTERNET_DEFAULT_HTTP_PORT, NULL,NULL,         INTERNET_SERVICE_HTTP, 0, 1u);     if(!hConnect)     {         InternetCloseHandle(hInetSession);         AfxMessageBox("---3");         return;      }     strURL = "/uploadImage?apiToken=aciB5aM%2FxsI4WkCnuN4RFAczLBxVBX2mkYUhngQh7efNbHN7YzG5rWPOy7Ww%2BEblzo1db%2FegAC50yepo3agiKsudaYwrL7xfYbaA8ydctS7WNO2butBhsw%3D%3D&photoIds=Ba9z4BfOlNoTe6%2FVJyahKlpqGliqCyVrUdEynq628FB6IVP%2FRwvqVQ%3D%3D";     HINTERNET hRequest = HttpOpenRequest(hConnect, "POST", strURL.c_str(), NULL, NULL, 0, INTERNET_FLAG_KEEP_CONNECTION, 1); // Пост запрос     if(!hRequest)     {         InternetCloseHandle(hConnect);         InternetCloseHandle(hInetSession);         AfxMessageBox("---4");         return;      }     BOOL bSend; std::string strAdd;     strAdd = "Content-Type: multipart/form-data; boundary=---------------------------11020459624021"; // Тип контента     bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD); // Добавляем необходимые параметры запроса     strAdd = "Content-Length: 921";     bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);     strAdd = "\\";     bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);     strAdd = "-----------------------------11020459624021";     bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);     strAdd = "Content-Disposition: form-data; name=\"pic1\"; filename=\"d:\\MyVC++\\~BackupOK\\1.JPG\"";     bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);     strAdd = "Content-Type: image/jpeg";     bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);     strAdd = "....................";     bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);     strAdd = "-----------------------------11020459624021--";     bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);     bSend = ::HttpSendRequest(hRequest, NULL, 0, (void*)strAdd.c_str(), strAdd.length());     CString strEdit="";     if(!bSend)     {         InternetCloseHandle(hRequest);         InternetCloseHandle(hConnect);         InternetCloseHandle(hInetSession);         AfxMessageBox("---1");         return;     }     else     {         // читаем данные         char  szData[204800];         DWORD dwBytesRead;         BOOL bRead =             ::InternetReadFile(             hRequest,             szData,sizeof(szData)-1,             &dwBytesRead);         szData[dwBytesRead] = 0;         if(bRead) {             strEdit = szData;             UpdateData(false);         }         else {             strEdit = "Нет данных";             UpdateData(false);                             }     }     AfxMessageBox(strEdit);     unsigned long ulSource = 0;     InternetSetFilePointer(hRequest, 0, NULL, FILE_BEGIN, NULL);     InternetReadFile(hRequest, (LPVOID)&cBuf, 200000, &dwRead);     InternetCloseHandle(hRequest); | 
| 
         
         
          
           Сообщ.
           #3
          
          , 
          
         
         | |
|  |  Не в ту тему. Вообще надо почитать про формирование POST запросов. http://www.codenet.ru/webmast/php/HTTP-POST.php Цитата  1. Content-Length: 831083 - это надо каким-то образом вычислять? 2. filename="d:\MyVC++\~BackupOK\1.JPG" - тут должен быть путь к моему локальному файлу? 1. Реальный размер отправляемых данных в байтах. 2. Не обязательно. PS лучше заюзать какую-нибудь обертку, а не руками отсылать. | 
| 
         
         
          
           Сообщ.
           #4
          
          , 
          
         
         | |
|  |  domencom, спасибо за ответ! В другом разделе я тоже интересуюсь на эту тему, на всякий случай. Пошел по ссылке читать про посты.   Цитата domencom @ Каких именно данных? Размер файла? 1. Реальный размер отправляемых данных в байтах. Цитата domencom @ Что значит не обязательно? 2. Не обязательно. | 
| 
         
         
          
           Сообщ.
           #5
          
          , 
          
         
         | |
|  | Цитата Lerik @  Что значит не обязательно? Не обязательно путь к файлу. Можно просто название файла. Цитата Lerik @  Размер файла? да. | 
| 
         
         
          
           Сообщ.
           #6
          
          , 
          
         
         | |
|  |  Наконец-то справился с HttpAnalyzer и посмотрел запрос от браузера. Оказывается filename="IMG_0699.JPG" - чисто номинальный параметр, чтобы сервер знал, как ему назвать тот файл, который он соберет из того, что передается ниже. А вот ниже, вместо многоточия "...................." передается файл в бинарном виде, чего я не делаю. Косяк найден. Цитата domencom @ Да нет, похоже это размер файла в байтах + длина строки остального запроса? (сорри, по ссылке сходил, но еще не дочитал :-) ) да.  | 
| 
         
         
          
           Сообщ.
           #7
          
          , 
          
         
         | |
|  | Цитата Lerik @  Да нет, похоже это размер файла в байтах + длина строки остального запроса? Ну если помимо файла отдаешь ещё текст, то естественно. Хотя судя по инфе, все что после Цитата в примере по ссылке, считается телом, даже "заголовки разделов". Ну как-то так значит. Content-Length: 209\r\n\r\n | 
| 
         
         
          
           Сообщ.
           #8
          
          , 
          
         
         | |
|  |  Всем спасибо, получилось!   А Content-Length: вообще передавать не надо, он сформируется и вычислится автоматически. |