Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.135.183.1] |
|
Сообщ.
#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: вообще передавать не надо, он сформируется и вычислится автоматически. |