我的send字符串如下:
char strSend[1000];
wsprintf(hostname,"GET /GET /11/QUERY.JSP?TIME=01/01/200101:01:01&TID=X213&LOGID=N2003&CALLID=55555555&SERVICEID=66666666&COMPANY1=qq1&COMPANY2=qq2&COMPANY3=国旗3&ADDRESS=北京&PHONE1=11111111&PHONE2=22222222&PHONE3=33333333 HTTP/1.0 %c%c",10,10);连接WEB服务器都正常,但是就是返回400的错误,我用CHttpFile类做用一样的GET语句就没有问题,而且WEB服务器接收参数正常,为什么SDK的就不对呢,是不是SEND函数有字节的限制或者其他的东西呢???请大家帮忙。
char strSend[1000];
wsprintf(hostname,"GET /GET /11/QUERY.JSP?TIME=01/01/200101:01:01&TID=X213&LOGID=N2003&CALLID=55555555&SERVICEID=66666666&COMPANY1=qq1&COMPANY2=qq2&COMPANY3=国旗3&ADDRESS=北京&PHONE1=11111111&PHONE2=22222222&PHONE3=33333333 HTTP/1.0 %c%c",10,10);连接WEB服务器都正常,但是就是返回400的错误,我用CHttpFile类做用一样的GET语句就没有问题,而且WEB服务器接收参数正常,为什么SDK的就不对呢,是不是SEND函数有字节的限制或者其他的东西呢???请大家帮忙。
Content-Type: text/xml; charset=utf-8
Content-Length: length400 的含义是:
无法找到网页
您正在搜索的网页可能已经删除、更名或暂时不可用。 --------------------------------------------------------------------------------请尝试下列操作:如果在“地址”栏中键入了网页地址,请检查其拼写是否正确。
打开 file:// 主页,寻找指向所需信息的链接。
单击后退按钮尝试其他链接。
HTTP 400 - 请求无效
Internet 信息服务--------------------------------------------------------------------------------技术信息(支持个人)详细信息:
Microsoft 支持
ASP中的Server.URLEncode在VC中的实现(2002-07-14) --------------------------------------------------------------------------------
一. 事情的起因:
从我的VC组件中试图用ServerXMLHTTP对象向服务器端的ASP页面发送一个QueryString,它的值为联系人的名字,这是中文字符,如:“http://localhost/tester/test.asp?username=郑昀”。希望ASP页面接收到的仍然是正常的中文字符,而不会是乱码。大家知道,ServerXMLHTTP对象在作HTTP操作之前,会先将URL转换为UTF8编码。而IIS接收时,会自动将这个UTF8编码的URL转换为Unicode编码,但是它有时会错误地丢掉奇数UTF8编码字符串的最后一个字节,所以得到就会是乱码。这个问题的描述可以参看《IIS是如何接收ServerXMLHTTP传过来的编码字符》。这样,对于我们的情况,我们希望能够在用SXH对象之前将URL字符串Encode一下。这样的做法在ASP中是通过Server.URLEncode来做的。下面我们就给出Visual C++中如何做到这一点的。(注意:这需要MFC。以后有空时,我们会给出STL实现的URLEncode)二. URLEncode的代码:
inline BYTE toHex(const BYTE &x){ return x > 9 ? x + 55: x + 48;}CString URLEncode(CString sIn){ CString sOut; const int nLen = sIn.GetLength() + 1; register LPBYTE pOutTmp = NULL; LPBYTE pOutBuf = NULL; register LPBYTE pInTmp = NULL; LPBYTE pInBuf =(LPBYTE)sIn.GetBuffer(nLen); BYTE b = 0; //alloc out buffer pOutBuf = (LPBYTE)sOut.GetBuffer(nLen*3 - 2);//new BYTE [nLen * 3]; if(pOutBuf) { pInTmp = pInBuf; pOutTmp = pOutBuf; // do encoding while (*pInTmp) { if(isalnum(*pInTmp)) *pOutTmp++ = *pInTmp; else if(isspace(*pInTmp)) *pOutTmp++ = '+'; else { *pOutTmp++ = '%'; *pOutTmp++ = toHex(*pInTmp>>4); *pOutTmp++ = toHex(*pInTmp%16); } pInTmp++; } *pOutTmp = ''; //sOut=pOutBuf; //delete [] pOutBuf; sOut.ReleaseBuffer(); } sIn.ReleaseBuffer(); return sOut;}
三. 测试代码:
CString strUnEncodeLinkTo("Globalhelp.xml?username=郑昀"); CString strLinkTo = URLEncode(strUnEncodeLinkTo); // strLinkTo的结果是: // "Globalhelp%2Exml%3Fusername%3D%D6%A3%EA%C0"
四. 说明:
这样,经URLEncode转换之后的URL,被IIS接收时,用QueryString(“username”)得到的就会是正确的中文字符了。请再看一下,下面这种情况:ASP的代码为:1 Dim strURL 2 strURL = "郑昀" 3 strURL = Server.URLEncode(strURL) 4 strURL = "http://localhost/tester/Receiver.asp?name=" & strURL 5 xmlhttp.setOption(0) = 936 6 xmlhttp.Open "POST",strURL,false 7 xmlhttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"8 xmlhttp.send第三行代码把中文字符Encode了一下。所以strURL就变为了“%D6%A3%EA%C0”。第五行代码的意思是,设置SXH对象的SXH_OPTION_URL_CODEPAGE的值为936,即GB2312。(而这个选项的缺省值为CP_UTF8,这就是为什么会将你的Unicode的URL字符串转换为UTF8的原因。)现在我们把它设置为GB2312这种codepage。会出现什么结果呢? 接收的ASP页面上是这么做的:1 Dim value2 value = Request.QueryString("name")这个value的值仍然会是“%D6%A3%EA%C0”,这就是设置codepage为GB2312的结果。如果将上面代码的第五行注释掉,那么这里的value就会是“郑昀”。
所以说SXH.setOption是可以控制转换用的codepage的。
老大哥哥说的不错,这个问题我也遇到过,不过已经解决了。我为了对付UTF-8 自己写了解码的类希望对你有帮助,我也用到了MFC,但关键部分的代码和MFC无关,稍微改动一下就可以了。
CString CUrlEncode::UrlDecodeUTF8(CString sIn)
{
CString sOut;
sOut = URLDecode(sIn);
int nLen = sOut.GetLength();
WCHAR * pWBuf = new WCHAR[nLen+1];
nLen = LdapUTF8ToUnicode(sOut,nLen+1,pWBuf,2*(nLen+1)); LPTSTR pStrOut = sOut.GetBuffer(2*nLen+1);
int nRet = WideCharToMultiByte(CP_ACP, 0, pWBuf, -1, pStrOut,2*nLen+1 , NULL, NULL);
sOut.ReleaseBuffer(); return sOut;
}
CString CUrlEncode::URLEncode(CString sIn)
{
CString sOut;
const int nLen = sIn.GetLength() + 1;
register LPBYTE pOutTmp = NULL;
LPBYTE pOutBuf = NULL;
register LPBYTE pInTmp = NULL;
LPBYTE pInBuf =(LPBYTE)sIn.GetBuffer(nLen);
BYTE b = 0;
//alloc out buffer
pOutBuf = (LPBYTE)sOut.GetBuffer(nLen * 3 - 2);//new BYTE [nLen * 3];
if(pOutBuf)
{
pInTmp = pInBuf;
pOutTmp = pOutBuf;
// do encoding
while (*pInTmp)
{
if(isalnum(*pInTmp))
*pOutTmp++ = *pInTmp;
else
if(isspace(*pInTmp))
*pOutTmp++ = '+';
else
{
*pOutTmp++ = '%';
*pOutTmp++ = toHex(*pInTmp>>4);
*pOutTmp++ = toHex(*pInTmp%16);
}
pInTmp++;
}
*pOutTmp = '\0';
//sOut=pOutBuf;
//delete [] pOutBuf;
sOut.ReleaseBuffer();
}
sIn.ReleaseBuffer();
return sOut;
}
CString CUrlEncode::URLDecode(CString sIn)
{
CString sOut;
sIn.Replace('+', ' ');
const int nLen = sIn.GetLength() + 1;
register LPBYTE pInTmp = NULL;
register LPBYTE pOutTmp = NULL;
LPBYTE pOutBuf = NULL;
LPBYTE pInBuf =(LPBYTE)sIn.GetBuffer(nLen);
//alloc out buffer
pOutBuf = (LPBYTE)sOut.GetBuffer(nLen * 3 - 2);//new BYTE [nLen * 3];
if(pOutBuf)
{
pInTmp = pInBuf;
pOutTmp = pOutBuf;
while (*pInTmp)
{
if (*pInTmp=='%')
{
pInTmp++;
if (isxdigit(pInTmp[0]) && isxdigit(pInTmp[1]))
{
*pOutTmp++ = (char) IntFromHex(pInTmp);
pInTmp += 2;
}
}
else
{
*pOutTmp ++ = *pInTmp++;
}
}
*pOutTmp = '\0';
}
sOut.ReleaseBuffer();
sIn.ReleaseBuffer();
return sOut;
} inline static BYTE toHex(const BYTE &x)
{
return x>9 ? (x+55):(x + 48);
}
inline static int IntFromHex(BYTE *pChars)
{
int Hi; // 高位
int Lo; // 低位
int Result; // 结果
Hi = pChars[0];
if ('0' <= Hi && Hi <= '9')
{
Hi -= '0';
}
else if ('a' <= Hi && Hi <= 'f')
{
Hi -= ('a'-10);
}
else if ('A' <= Hi && Hi <= 'F')
{
Hi -= ('A'-10);
}
Lo = pChars[1];
if ('0' <= Lo && Lo <= '9')
{
Lo -= '0';
}
else if ('a' <= Lo && Lo <= 'f')
{
Lo -= ('a'-10);
}
else if ('A' <= Lo && Lo <= 'F')
{
Lo -= ('A'-10);
}
Result = Lo + (16 * Hi);
return (Result);
}这样编码和解码的问题都解决了。
//
// 娭悢柤 : CUrlEncode::EnCode
//
// 婡擻 : URL僄儞僐乕僪
//
// 婡擻愢柧 : csSource偵懳偟偰URL僄儞僐乕僪張棟傪峴偄丄寢壥傪csCode偵弌椡偡傞丅
//
//----------------------------------------------------------------------------
void CUrlEncode::EnCode(bool IsMsgHeader, bool IsJisConvert)
{
int iCodeType;
int iPrevCodeType = 0;
char strBuf[10]; // 嶌嬈僶僢僼傽
CString csTarget; // 曄姺懳徾暥帤楍
CString csConverted; // 曄姺屻偺暥帤楍
LPCTSTR strSrc = (LPCTSTR)csSource;
csCode.Empty();
// 僔儞僌儖僶僀僩僐乕僪丒儅儖僠僶僀僩僐乕僪暘棧
csTarget.Empty();
for (;;) {
iCodeType = GetSJisChar(strSrc, strBuf);
strSrc += iCodeType;
if (iCodeType < 0) break; // 僄儔乕
if (iPrevCodeType != iCodeType && iPrevCodeType != 0) {
// 僔儞僌儖僶僀僩<->儅儖僠僶僀僩偺嫬栚
csConverted.Empty();
if (iPrevCodeType == 2) {
DoUrlEncode(csTarget, csConverted, IsJisConvert, NULL);
} else {
DoUrlEncode(csTarget, csConverted, false, (LPCTSTR)m_csExcept);
};
csCode += csConverted;
csTarget.Empty();
};
if (iCodeType == 0) break;
csTarget += strBuf;
iPrevCodeType = iCodeType;
};
}void CUrlEncode::DoUrlEncode(CString csSrcData, CString &csDstData, bool IsJisConvert, LPCTSTR strExcept)
{
long lngLength; // 僆儕僕僫儖暥帤楍(csSource)偺挿偝
long lngPos; // 張棟埵抲
char chSrc; // 張棟懳徾僐乕僪(1byte)
LPCTSTR strSrc; // 僆儕僕僫儖暥帤楍傊偺億僀儞僞
char strBuf[10]; // 僐乕僪->16恑悢曄姺梡嶌嬈僶僢僼傽
bool IsExcept;
// 僐乕僪曄姺
if (IsJisConvert) {
csSrc = csSrcData;
ConvSJisToJis();
csSrcData = csDst;
};
// UrlEncode
lngLength = csSrcData.GetLength();
strSrc = (LPCTSTR)csSrcData;
for (lngPos = 0; lngPos < lngLength; lngPos++) {
chSrc = *(strSrc + lngPos);
IsExcept = false;
if (strExcept != NULL) {
for (long lngPos = 0; *(strExcept + lngPos) != 0; lngPos++) {
if (*(strExcept + lngPos) == chSrc) {
IsExcept = true;
break;
};
};
};
if (('0' <= chSrc && chSrc <= '9')
|| ('a' <= chSrc && chSrc <= 'z')
|| ('A' <= chSrc && chSrc <= 'Z')
|| IsExcept) {
// 塸悢帤憡摉偺僐乕僪傑偨偼曄姺懳徾奜僐乕僪偼偦偺傑傑
csDstData += chSrc;
} else if (chSrc == ' ') {
// 僗儁乕僗偼'+'偵曄姺偡傞
csDstData += '+';
} else {
// 僄僗働乕僾('%')亄16恑悢昞帵偵抲偒姺偊傞
sprintf(strBuf, "%0.2X", (unsigned char)chSrc);
csDstData += "%";
csDstData += strBuf;
};
};
}//----------------------------------------------------------------------------
//
// 娭悢柤 : CUrlEncode::DeCode
//
// 婡擻 : URL僨僐乕僪
//
// 婡擻愢柧 : csSource偵懳偟偰URL僨僐乕僪張棟傪峴偄丄寢壥傪csCode偵弌椡偡傞丅
//
//----------------------------------------------------------------------------
void CUrlEncode::DeCode(bool IsMsgHeader, bool IsJisConvert)
{
long lngLength; // 僄儞僐乕僪暥帤楍(csCode)偺挿偝
long lngPos; // 張棟埵抲
char chSrc; // 張棟懳徾僐乕僪(1byte)
LPCTSTR strSrc; // 僄儞僐乕僪暥帤楍傊偺億僀儞僞
char *strEr; // strtoul梡僄儔乕弌椡
CString csHexCode; // 16恑昞婰
csSource.Empty();
lngLength = csCode.GetLength();
strSrc = (LPCTSTR)csCode;
for (lngPos = 0; lngPos < lngLength; lngPos++) {
chSrc = *(strSrc + lngPos);
if (chSrc != '%') {
// 僄僗働乕僾('%')偑側偄応崌偼偦偺傑傑捛壛丅
csSource += chSrc;
} else {
// 僄僗働乕僾('%')亄16恑悢->捠忢偺暥帤僐乕僪偵曄姺偡傞丅
if (lngPos + 2 < lngLength) {
csHexCode.Empty();
csHexCode += *(strSrc + (++lngPos));
csHexCode += *(strSrc + (++lngPos));
csSource += (unsigned char)strtoul(csHexCode, &strEr, 16);
if (*strEr != 0) {
throw(cderException);
return;
};
} else {
throw(cderException);
return;
};
};
};
if (IsJisConvert) {
csSrc = csSource;
ConvJisToSJis();
csSource = csDst;
};
}