在 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");
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);
VT_UI1(無符號位元組)、單維度、元素數等於 POST 資料位元組數vt = VT_ARRAY | VT_UI1,parray 指向 SAFEARRAYapplication/x-www-form-urlencoded,否則伺服器可能不解析主體Navigate2 為擴展版本https://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/reference/Objects/WebBrowser.aspSAFEARRAYs made easier掌握 SAFEARRAY 與 TVariant 互轉技巧,即可在 C++ Builder 中靈活實現 Web 自動化操作、表單提交、API 呼叫等進階功能。