На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
    > WinHTTP - POST запрос
      Привет всем!

      Осваиваю библиотеку winhhtp. мне нужно сделать POST запрос на сервер и передать ему пару параметров (pass=123, username=user, flag=1 и т.д.)
      Куда добавлять эти данные? В примерах, которые я нашел есть только для GET запроса, а там никаких данных на сервер не передается.

      Также потом мне нужно будет отправить как-то файл на сервер. Как его прикрепить к POST-запросу?

      Надеюсь на вашу помощь! заранее спасибо!
        MSDN
        HttpOpenRequest
        HttpSendRequest
          ExpandedWrap disabled
                HINTERNET hInetSession;
                string strURL = ""; 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)
                    return -1;
             
                HINTERNET hConnect = InternetConnect(hInetSession, "www.kino-teatr.ru", INTERNET_DEFAULT_HTTP_PORT, NULL,NULL,
                            INTERNET_SERVICE_HTTP, 0, 1u);
                if(!hConnect) { InternetCloseHandle(hInetSession); return -1; }
             
                strURL = "/search/";
             
                HINTERNET hRequest = HttpOpenRequest(hConnect, "POST", strURL.c_str(), NULL, NULL, 0, INTERNET_FLAG_KEEP_CONNECTION, 1); // Пост запрос
                if(!hRequest) { InternetCloseHandle(hConnect); InternetCloseHandle(hInetSession); return -1; }
             
                BOOL bSend; string strAdd;
                strAdd = "Content-Type: application/x-www-form-urlencoded"; // Тип контента
                    bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD); // Добавляем необходимые параметры запроса
                strAdd = "Accept-Encoding: compress, gzip";
                    bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);
                strAdd = "Accept: text/html, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap";
                    bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);
             
                strAdd = "text=Transformers&movie=1"; // Здесь передаются необходимые переменные
            // По аналогии: "pass=123&username=user&flag=1"
             
                bSend = ::HttpSendRequest(hRequest, NULL, 0, (void*)strAdd.c_str(), strAdd.length());
             
                if(!bSend)
                {
                    InternetCloseHandle(hRequest);
                    InternetCloseHandle(hConnect);
                    InternetCloseHandle(hInetSession);
                    return -1;
                }
             
                unsigned long ulSource = 0;
             
                InternetSetFilePointer(hRequest, 0, NULL, FILE_BEGIN, NULL);
                InternetReadFile(hRequest, (LPVOID)&cBuf, 200000, &dwRead);
                InternetCloseHandle(hRequest);
            С этим разобрался, спасибо!

            Мне нужно отправлять данные строковые. Я делал так:

            ExpandedWrap disabled
              ...
              bResults = WinHttpSendRequest( hRequest,
                                     szContentType,
                                             wcslen(szContentType),
                                     postData,
                                             sizeof(postData),
                                     sizeof(postData),
                                             0 );
              ...


            и postData содержит несколько пар имя=значение&имя=значение...

            А теперь мне еще нужно отправить дополнительно .xml файл вместе с этим.
            На форме у них это компонент <input id="file" type="file" value="" name="file"/>
            по отправке содержимое файла отправляется на сервер.

            Как мне прикрепить этот файл к тому, что у меня уже есть?
              Никто не знает как такое сделать?

              У меня сейчас одна версия, это добавить новую пару имя=значение, file="содержимое файла". Но не уверен, что это правильно.
              Т.к. я Fiddler'ом смотрел как отправляются файлы из таких форм... Они отправляются как вложения к запросу и имеют свой Content-Type.

              Подскажите как прикрепить файл?? Я нашел примеры как просто сделать POST-запрос и отправить файл с запросом. И там не указывается никакой доп.инфорации. А у меня имя параметра при отправке должно указываться (file), а также у меня есть еще другие параметры, которые я отправляю на сервер.

              Спасибо.
                Здравствуйте!

                Решил не создавать новую тему, так как моя проблема практически идентична проблеме человека, создавшего эту тему. Отличие лишь в том, что мне нужно пройти авторизацию на сайте www.vkontakte.ru и получить сводку новостей. Листинг моей программы следующий (использую MFC):

                ExpandedWrap disabled
                  #include "stdafx.h"
                  #include "afxinet.h"
                  #include <fstream>
                   
                  using namespace std;
                   
                  int _tmain(int argc, _TCHAR* argv[])
                  {
                      CInternetSession se(L"My Session");
                      CHttpConnection *pConnection = NULL;
                      CHttpFile *pFile1 = NULL, *pFile2 = NULL;
                      char buffer[1024];
                      const TCHAR hdrs[] = L"Content-Type: application/x-www-form-urlencoded";
                      const TCHAR post[] = L"email=my_email@my_email.my&pass=my_pass&expire=1";
                      UINT nBytesRead = 0;
                      try
                      {
                          pConnection = se.GetHttpConnection(L"www.vkontakte.ru", 0, 80, 0, 0);
                          pFile1 = pConnection->OpenRequest(L"POST", L"login.php", NULL, 1, 0, 0, INTERNET_FLAG_KEEP_CONNECTION);
                          pFile1->SendRequest(hdrs, wcslen(hdrs), (LPVOID)post, wcslen(post));
                          pFile2 = pConnection->OpenRequest(L"GET", L"newsfeed.php", NULL, 1, 0, 0, INTERNET_FLAG_KEEP_CONNECTION);
                          pFile2->SendRequest();
                          ofstream fnews(L"news.html",ios::out|ios::binary);
                          if (fnews.is_open())
                              for (;;)
                              {
                                  nBytesRead = pFile2->Read(buffer, 1024 - 1);
                                  if (nBytesRead == 0)
                                      break;
                                  buffer[nBytesRead] = 0;
                                      fnews << buffer;
                              }
                      }
                      catch(CInternetException* e)
                      {
                          e->ReportError();
                          e->Delete();
                      }
                      pFile1->Close();
                      pFile2->Close();
                      pConnection->Close();
                      se.Close();
                      system("start news.html");
                      _getch();
                      return 0;
                  }


                После выполнения програмы в открывшемся файле не новости, а все та же страница авторизации. Прошу помочь разобраться, что делаю не так. В теме на этом форуме каким-то образом подключаются :/
                  Держи рабочий код. У меня все авторизовалось и новости извлеклись. Правда это не MFC, а Win32 API :)

                  ExpandedWrap disabled
                    {
                        HINTERNET hInternet =
                            ::InternetOpen(
                                TEXT("WinInet Test"),
                                INTERNET_OPEN_TYPE_PRECONFIG,
                                NULL,NULL,
                                0);
                     
                        if (hInternet != NULL) {
                            // открываем HTTP сессию
                            HINTERNET hConnect =
                                ::InternetConnect(
                                    hInternet,
                                    TEXT("vkontakte.ru"),
                                    INTERNET_DEFAULT_HTTP_PORT,
                                    NULL,NULL,
                                    INTERNET_SERVICE_HTTP,
                                    0,
                                    1u);
                     
                            if (hConnect != NULL) {
                                // открываем запрос
                                HINTERNET hRequest =
                                    ::HttpOpenRequest(
                                        hConnect,
                                        TEXT("POST"),
                                        TEXT("/login.php"),
                                        NULL,
                                        NULL,
                                        0,
                                        INTERNET_FLAG_KEEP_CONNECTION,
                                        1);
                     
                                if (hRequest != NULL) {
                                    
                                    char strOpt[] = _T("email=azote@****.ru&pass=*********");
                                    
                                    BOOL bSend; string strAdd;
                                
                                    // Формируем заголовок
                                    strAdd = "Accept: */*";
                                    bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);
                                    strAdd = "Content-Type: application/x-www-form-urlencoded";
                                    bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);
                     
                                    // посылаем запрос
                                    bSend = ::HttpSendRequest(hRequest, NULL, 0, (void*)strOpt, strlen(strOpt));
                     
                                    hRequest = ::HttpOpenRequest(
                                         hConnect,
                                         TEXT("GET"),
                                         TEXT("/newsfeed.php"),
                                         NULL,
                                         NULL,
                                         0,
                                         INTERNET_FLAG_KEEP_CONNECTION,
                                         1);
                     
                                    bSend = ::HttpSendRequest(hRequest, NULL, 0, NULL, 0);
                     
                                    if (bSend) {
                                            // читаем данные
                                            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);
                                            }
                                    }
                     
                                    // закрываем запрос
                                    ::InternetCloseHandle(hRequest);
                                }
                                // закрываем сессию
                                ::InternetCloseHandle(hConnect);
                            }
                            // закрываем WinInet
                            ::InternetCloseHandle(hInternet);
                        }
                    }
                    Спасибо, AZote! Премного благодарен! :)
                      Цитата AZote @
                      Держи рабочий код. У меня все авторизовалось и новости извлеклись. Правда это не MFC, а Win32 API :)

                      ExpandedWrap disabled
                        {
                            HINTERNET hInternet =
                                ::InternetOpen(
                                    TEXT("WinInet Test"),
                                    INTERNET_OPEN_TYPE_PRECONFIG,
                                    NULL,NULL,
                                    0);
                         
                            if (hInternet != NULL) {
                                // открываем HTTP сессию
                                HINTERNET hConnect =
                                    ::InternetConnect(
                                        hInternet,
                                        TEXT("vkontakte.ru"),
                                        INTERNET_DEFAULT_HTTP_PORT,
                                        NULL,NULL,
                                        INTERNET_SERVICE_HTTP,
                                        0,
                                        1u);
                         
                                if (hConnect != NULL) {
                                    // открываем запрос
                                    HINTERNET hRequest =
                                        ::HttpOpenRequest(
                                            hConnect,
                                            TEXT("POST"),
                                            TEXT("/login.php"),
                                            NULL,
                                            NULL,
                                            0,
                                            INTERNET_FLAG_KEEP_CONNECTION,
                                            1);
                         
                                    if (hRequest != NULL) {
                                        
                                        char strOpt[] = _T("email=azote@****.ru&pass=*********");
                                        
                                        BOOL bSend; string strAdd;
                                    
                                        // Формируем заголовок
                                        strAdd = "Accept: */*";
                                        bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);
                                        strAdd = "Content-Type: application/x-www-form-urlencoded";
                                        bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);
                         
                                        // посылаем запрос
                                        bSend = ::HttpSendRequest(hRequest, NULL, 0, (void*)strOpt, strlen(strOpt));
                         
                                        hRequest = ::HttpOpenRequest(
                                             hConnect,
                                             TEXT("GET"),
                                             TEXT("/newsfeed.php"),
                                             NULL,
                                             NULL,
                                             0,
                                             INTERNET_FLAG_KEEP_CONNECTION,
                                             1);
                         
                                        bSend = ::HttpSendRequest(hRequest, NULL, 0, NULL, 0);
                         
                                        if (bSend) {
                                                // читаем данные
                                                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);
                                                }
                                        }
                         
                                        // закрываем запрос
                                        ::InternetCloseHandle(hRequest);
                                    }
                                    // закрываем сессию
                                    ::InternetCloseHandle(hConnect);
                                }
                                // закрываем WinInet
                                ::InternetCloseHandle(hInternet);
                            }
                        }

                      Попытался подобным образом спарсить страницу со списком игр в STEAM (новичек в с++):

                      ExpandedWrap disabled
                            {
                                HINTERNET hInternet =
                                    ::InternetOpen(
                                        TEXT("WinInet Test"),
                                        INTERNET_OPEN_TYPE_PRECONFIG,
                                        NULL,NULL,
                                        0);
                            
                                if (hInternet != NULL) {
                                    // открываем HTTP сессию
                                    HINTERNET hConnect =
                                        ::InternetConnect(
                                            hInternet,
                                            TEXT("http://steamcommunity.com/profiles/76561198029313508"),
                                            INTERNET_DEFAULT_HTTP_PORT,
                                            NULL,NULL,
                                            INTERNET_SERVICE_HTTP,
                                            0,
                                            1u);
                         
                                            // Формируем заголовок
                                            strAdd = "Accept: */*";
                                            bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);
                                            strAdd = "Content-Type: application/x-www-form-urlencoded";
                                            bSend = ::HttpAddRequestHeaders(hRequest, strAdd.c_str(), strAdd.length(), HTTP_ADDREQ_FLAG_ADD);
                            
                                            // посылаем запрос
                                            bSend = ::HttpSendRequest(hRequest, NULL, 0, (void*)strOpt, strlen(strOpt));
                            
                                            hRequest = ::HttpOpenRequest(
                                                 hConnect,
                                                 TEXT("GET"),
                                                 TEXT("/games/?tab=all"),
                                                 NULL,
                                                 NULL,
                                                 0,
                                                 INTERNET_FLAG_KEEP_CONNECTION,
                                                 1);
                            
                                            bSend = ::HttpSendRequest(hRequest, NULL, 0, NULL, 0);
                            
                                            if (bSend) {
                                                    // читаем данные
                                                    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);
                                                    }
                                            }
                            
                                            // закрываем запрос
                                            ::InternetCloseHandle(hRequest);
                                        }
                                        // закрываем сессию
                                        ::InternetCloseHandle(hConnect);
                                    }
                                    // закрываем WinInet
                                    ::InternetCloseHandle(hInternet);
                                }
                            }


                      Приложение не компилируется.
                      Ошибка: fatal error C1189: #error: Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d] C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\include\afx.h 24
                        МОЖЕТ КТОНЕБУТЬ НАПИСАТЬ ПРОСТОЙ И ПОНЯТНЫЙ ПРИМЕР ДЛЯ ЛАМЕРА?
                        С ПОСТРОЧЬНЫМИ КОМЕНТАРИЯМИ ГДЕ ЗАПРОС - ГДЕ ЧТО
                          Цитата Maper @
                          ПРИМЕР ДЛЯ ЛАМЕРА

                          Самое печальное, что ламер даже учиться не изволит. Мусолишь эту тему уже который месяц и примеров тебе понавываливали уже вагон и тележку.
                            Тема посылки POST запроса настолько глубока и всеобъемлюща, что ей можно заниматься всю жизнь, защитить диссертацию, и так и не постичь всю ее глубину.
                            0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                            0 пользователей:


                            Рейтинг@Mail.ru
                            [ Script execution time: 0,0412 ]   [ 16 queries used ]   [ Generated: 3.05.24, 09:10 GMT ]