POST教程笔记 - Cookie方式登录网站

www.cctry.com post教程

注意,本文章并非教程

获取Cookie

#import "C:\\Windows\\SysWow64\\winhttp.dll" no_namespace
#define Get_WinHttp_RspString(IWinHttpRequestPtr_Obj, CString_Obj){                \
    _variant_t varRspBody = IWinHttpRequestPtr_Obj->GetResponseBody();            \
    ULONG dataLen = varRspBody.parray->rgsabound[0].cElements;                    \
    char *pContentBuffer = (char *)varRspBody.parray->pvData;                    \
    CString_Obj = pContentBuffer;}

void getWinHttpRspString(IWinHttpRequestPtr &pHttpReq, CString& strBuffer)
{
    _variant_t varRspBody = pHttpReq->GetResponseBody();
    ULONG dataLen = varRspBody.parray->rgsabound[0].cElements;                    
    char *pContentBuffer = (char *)varRspBody.parray->pvData;                    
    strBuffer = pContentBuffer;
}




void Cidc816LoginDlg::OnBnClickedButton1()
{
    CString strName, strPwd;
//     GetDlgItemText(IDC_EDIT1, strName);
//     GetDlgItemText(IDC_EDIT2, strPwd);
//     if (strPwd == L"" || strName == L"")
//     {
//         MessageBox(L"用户名密码不能空");
//         return;
//     }
//
//     strName = L"XXX";
//     strPwd  = L"XXX";


    IWinHttpRequestPtr pHttpReq = NULL;
    HRESULT hr = pHttpReq.CreateInstance(__uuidof(WinHttpRequest));
    if (FAILED(hr))
        return;

    // 这里要注意需要POST的网址
    hr = pHttpReq->Open(L"POST", L"http://www.idc816.com/chklogin.asp");
    if (FAILED(hr))
        return;

     pHttpReq->SetRequestHeader(L"Content-Type", L"application/x-www-form-urlencoded");

     // 这里是重点,为了获取Cookie,关闭掉WinHttp的重定向功能
     // COleVariant varFalse = VARIANT_FALSE;
     // hr = pHttpReq->put_Option(WinHttpRequestOption_EnableRedirects, varFalse);
     pHttpReq->Option[WinHttpRequestOption_EnableRedirects] = VARIANT_FALSE;


    variant_t varBody = NULL;
    // 这里也需要注意,字段不要写错了
    varBody = L"u_name=XXX&u_password=XXX&imageField.x=28&imageField.y=11";
    hr = pHttpReq->Send(varBody);
    if (FAILED(hr))
        return;

    CString strCntBuffer;
    getWinHttpRspString(pHttpReq, strCntBuffer);


    long status = pHttpReq->GetStatus();
    
    CString strSucKey(_T("/Manager/"));
    if (status == 302 && strCntBuffer.Find(strSucKey) != -1)
    {
        _bstr_t bstrAllHeader = \
            pHttpReq->GetAllResponseHeaders();    // 需要获取所有Cookie,所以不能使用GetResponseHeader
        CString strCookie = getCookieString(CString((LPCTSTR)bstrAllHeader));
        SetDlgItemText(IDC_EDIT3, strCookie);
        MessageBox(_T("登陆成功!"));
    }
    else {
        MessageBox(_T("登陆失败!"));
    }
    
}

以上code中的getCookieString如下:

/*

Cache-Control: private
Content-Length: 107
Content-Type: text/html
Location: /Manager/
Server: Microsoft-IIS/8.0
Set-Cookie: user%5Fpwd=1329c273dda5a8c3; path=/
Set-Cookie: user%5Fname=winuser; path=/
Set-Cookie: safecode=8de86d96685c1249; path=/
X-Powered-By: ASP.NET
Date: Wed, 04 Nov 2015 12:15:46 GMT
*/

CString Cidc816LoginDlg::getCookieString(CString strResponseHeader)
{
    CString strCookie;

    int nPos = strResponseHeader.Find(L"Set-Cookie:");
    if (-1 == nPos) return NULL;
    int nCount = strResponseHeader.GetLength() - nPos;
    strResponseHeader = strResponseHeader.Right(nCount);

    nPos = strResponseHeader.Find(L"X-Powered-By:");
    if (-1 == nPos) return NULL;
    strCookie = strResponseHeader.Left(nPos);
    

    return strCookie;
}

对比VC驿站SYC老大的代码

CString GetCookieString(CString& strRspHeader)
{
    CString retCookie, strKey = _T("Set-Cookie: ");
    int iBegin = 0, iEnd = 0;
    while(iBegin < strRspHeader.GetLength())
    {
        iBegin = strRspHeader.Find(strKey, iBegin);
        if (iBegin >= 0)
        {
            iEnd = strRspHeader.Find(_T("\r\n"), iBegin);
            if (iEnd > 0)
            {
                retCookie += strRspHeader.Mid(iBegin, iEnd-iBegin+2);
                iBegin = iEnd;
            }
        }else{
            break;
        }
    }

    return retCookie;
}

 

 获取的Cookie

Set-Cookie: safecode=840b0ce1c0fc85c1; path=/
Set-Cookie: user%5Fpwd=9ca701ff68e6bac3; path=/
Set-Cookie: user%5Fname=winuser; path=/
Set-Cookie: ASPSESSIONIDAATATQQC=FADLFEABIKELJDBJHFPEBIOP; path=/

 

获取Cookie完成后,可以尝试不登陆进行用户信息的获取,代码如下:

 

void Cidc816LoginDlg::OnBnClickedButton2()
{
    IWinHttpRequestPtr pHttpReq;
    HRESULT hr = pHttpReq.CreateInstance(__uuidof(WinHttpRequest));
    if (FAILED(hr)) return;

    hr = pHttpReq->Open(_T("GET"), _T("http://www.idc816.com/manager/usermanager/default2.asp"));
    if (FAILED(hr)) return;

    CString strCookie;
    GetDlgItemText(IDC_EDIT4, strCookie);
    if (strCookie.GetLength() > 0)
    {   // 设置Cookie是本课重点 AllocSysString转换为bstr_t格式
        pHttpReq->SetRequestHeader(_T("Cookie"), strCookie.AllocSysString());
    }

    hr = pHttpReq->Send();
    if (FAILED(hr)) return;

    CString strCntBuffer;
    Get_WinHttp_RspString(pHttpReq, strCntBuffer);

    CString strTel = GetMidStrByLAndR(strCntBuffer, _T("u_telphone  value=\""), _T("\""));
    SetDlgItemText(IDC_EDIT5, strTel);

    CString strCity = GetMidStrByLAndR(strCntBuffer, _T("u_city value=\""), _T("\""));
    SetDlgItemText(IDC_EDIT6, strCity);

    CString strContrack = GetMidStrByLAndR(strCntBuffer, _T("u_contract  value=\""), _T("\""));
    SetDlgItemText(IDC_EDIT7, strContrack);

    if (strTel.IsEmpty() || strCity.IsEmpty() || strContrack.IsEmpty())
    {
        MessageBox(_T("获取用户信息失败!"));
    }
}

 

最后效果

 

posted @ 2015-11-04 20:53  Lthis  阅读(1753)  评论(0编辑  收藏  举报