首先,在Win95+VC6+IE4+MSXML3下,使用MSXML3的XMLHTTP在open时会发生错误(抛出异常,异常码为EFAIL,异常描述为空),个人认为是wininet和urlmon的问题(本人并未深入确认,本想安装IE5/5.5再测试,但无奈该版本太古老,找不到安装包,只能找到所谓绿色版)。
既然MSXML3的XMLHTTP无法使用,只好使用CInternetSession自行编写了:
void Send(Joytech::MSXML3::IXMLDOMDocument documentSend, const CString& url, const CString& soapAction, Joytech::MSXML3::IXMLDOMDocument& documentRecv)
{
static LPCTSTR header = _T("Accept: */*\r\n\
Accept-Language: zh-cn\r\n\
X-Requested-With: TWenXMLHttpRequest\r\n\
Content-Type: text/xml; charset=UTF-8\r\n\
UA-CPU: x86\r\n\
Accept-Encoding: gzip, deflate\r\n\
SOAPAction: ");
CString strHeader = header + soapAction + _T("\r\n");
DWORD dwServiceType;
CString strServer, strObject;
INTERNET_PORT nPort = 80;
//vc6版本的AfxParseURL不支持INTERNET_SERVICE_HTTPS
if (!AfxParseURL(url, dwServiceType, strServer, strObject, nPort) || (dwServiceType != INTERNET_SERVICE_HTTP))
throw new Joytech::Exception::CJoytechException(_T("url中的协议出错!"));
CString xml = documentSend.GetXml();
CInternetSession session;
CHttpConnection* pConnection = session.GetHttpConnection(strServer, nPort);
CHttpFile* pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, strObject);
pFile->SendRequest(strHeader, (LPVOID)(LPCTSTR)xml, xml.GetLength() * sizeof(TCHAR));
DWORD dwRet;
pFile->QueryInfoStatusCode(dwRet);
if(dwRet != HTTP_STATUS_OK) throw new Joytech::Exception::CJoytechException(_T("XMLHTTP状态出错!"));
CString strXML;
int nSize = pFile->GetLength();
{
CString strRead;
while(pFile->ReadString(strRead)) strXML += strRead;
}
pFile->Close();
delete pFile;
pConnection->Close();
delete pConnection;
session.Close();
Joytech::MSXML3::CreateXMLDocument(documentRecv);
documentRecv.loadXML(Joytech::StringConvert::Joytech_UTF82T((LPCSTR)strXML));//strXML虽然是CString类型,但内部的数据其实是UTF8(依赖于WebService服务器的xml序列化编码)的格式,因此需要手动转换为LPCTSTR格式
}
其中有两点需要注意:
1. 如果要支持https等协议,必须自行编写URL解析函数,因为VC6版本的URL解析函数AfxParseURL仅支持INTERNET_SERVICE_URL、INTERNET_SERVICE_FTP、INTERNET_SERVICE_GOPHER和INTERNET_SERVICE_HTTP四种。
2. 对于从服务器端返回的数据,虽然在代码中是使用pFile->ReadString取得的,并且是CString类型,但并不能简单地将之作为CString处理;一定要注意到,返回的xml文本是有编码的,一般为utf8!并且,在转换编码为LPCTSTR时,需要注意,Win95下的API函数MultiByteToWideChar/WideCharToMultiByte不支持UTF8,因此需要自己编写。