首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

CPPWebBrowser PostData 正確設置方法:SAFEARRAY 與 TVariant 轉換實戰

     編輯:關於C++

在 C++ Builder 中使用 TCppWebBrowser 元件進行 HTTP POST 請求時,Navigate 方法的 PostData 參數必須為特定結構的 SAFEARRAY,直接傳遞字串會導致伺服器接收不到參數。本文提供兩種經驗證可行的正確實作方案。

問題重現

WideString URL = "https://www.bianceng.cn/maker/pass.asp";
String ParamString = "username=test&password=12345";
TVariant *PostData = new TVariant(ParamString); // 錯誤:伺服器收不到參數
CPPWebBrowser->Navigate(URL, 0, 0, PostData, 0);

GET 方式拼接 URL 雖可行但不適用於大量資料或敏感資訊。

方案一:完整封裝函式(推薦)

void __fastcall TForm1::WebPostData(TCppWebBrowser *CppWebBrowser, String sURL, String sPostData) {
    BSTR bstrHeaders = NULL;
    TVariant vFlags = {0}, vTargetFrameName = {0}, vPostData = {0}, vHeaders = {0};
    LPSAFEARRAY psa;
    LPCTSTR cszPostData = sPostData.c_str();
    UINT cElems = lstrlen(cszPostData);
    LPSTR pPostData;
    LPVARIANT pvPostData;

    // 設定 Content-Type 標頭
    bstrHeaders = SysAllocString(L"Content-Type: application/x-www-form-urlencoded\r\n");
    if (!bstrHeaders) {
        Application->MessageBox("Could not allocate bstrHeaders", "Warning", MB_OK | MB_ICONWARNING);
        return;
    }
    V_VT(&vHeaders) = VT_BSTR;
    V_BSTR(&vHeaders) = bstrHeaders;

    // 建立 SAFEARRAY 載荷
    pvPostData = &vPostData;
    if (pvPostData) {
        VariantInit(pvPostData);
        psa = SafeArrayCreateVector(VT_UI1, 0, cElems);
        if (!psa) return;
        SafeArrayAccessData(psa, (LPVOID*)&pPostData);
        memcpy(pPostData, cszPostData, cElems);
        SafeArrayUnaccessData(psa);
        V_VT(pvPostData) = VT_ARRAY | VT_UI1;
        V_ARRAY(pvPostData) = psa;
    }

    CppWebBrowser->Navigate((TVariant)sURL, &vFlags, &vTargetFrameName, &vPostData, &vHeaders);
}

呼叫範例:

WebPostData(CppWebBrowser1, "https://211.91.2.221/pass.asp", "test=333333&PassWord=343200");

方案二:Borland 官方技術文件範例

TVariant vtEmpty;
TVariant vtPostDataArray;
char *str = "action=LogMeIn&username=MyName&password=MyPass";
SAFEARRAY FAR *psa = NULL;
SAFEARRAYBOUND sabound[1];
sabound[0].cElements = strlen(str);
sabound[0].lLbound = 0;
psa = SafeArrayCreate(VT_UI1, 1, sabound);

for (unsigned int n = 0; n < strlen(str); n++) {
    SafeArrayPutElement(psa, (long*)&n, (void*)&str[n]);
}

vtEmpty.vt = VT_EMPTY;
vtPostDataArray.vt = VT_ARRAY;
vtPostDataArray.SetSAFEARRAY(psa); // 或 vtPostDataArray = psa;

TVariant vAddress = "https://my.server/test/postresults.asp";
CppWebBrowser1->Navigate2(&vAddress, &vtEmpty, &vtEmpty, &vtPostDataArray, &vtEmpty);
SafeArrayDestroy(psa);

核心技術要點

  • SAFEARRAY 結構:元素型別 VT_UI1(無符號位元組)、單維度、元素數等於 POST 資料位元組數
  • TVariant 包裝:vt = VT_ARRAY | VT_UI1,parray 指向 SAFEARRAY
  • Content-Type 標頭:必須設定 application/x-www-form-urlencoded,否則伺服器可能不解析主體
  • Navigate vs Navigate2:參數相容,Navigate2 為擴展版本

參考資源

  • MSDN WebBrowser 元件參考:https://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/reference/Objects/WebBrowser.asp
  • Borland 社群 SAFEARRAY 教學:SAFEARRAYs made easier

掌握 SAFEARRAY 與 TVariant 互轉技巧,即可在 C++ Builder 中靈活實現 Web 自動化操作、表單提交、API 呼叫等進階功能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved