• 15587阅读
  • 18回复

[提问]【提问】给http发送请求,中文总出现乱码现象? [复制链接]

上一主题 下一主题
离线tasteprogram
 
只看楼主 倒序阅读 楼主  发表于: 2005-09-22
— 本帖被 XChinux 从 Qt基础编程 移动到本区(2013-04-01) —
各位朋友,大家好!

本人用QT开发了一个socket应用客户端,就是给http服务器发送请求,通过这个请求传递一些参数给http服务器上的后台程序。该功能已经实现。就是遇到了中文编码问题。
QT的QString是unicode编码,我将其转换到gbk,然后发送到服务器,但总是乱码。
发送的http头如下:
GET /asp/operationalarm.asp?message=中文测试 HTTP/1.1
Host:
Accept:*/*
User-Agent:Mozilla/4.0
Content-Type: text/html; charset="gb2312"

转换代码如下:
QGbkCodec *codec = new QGbkCodec();
QCString str = codec->fromUnicode( httpmsg,len );

请问各位大侠问题出在哪里?谢谢,复函为盼!
[ 此贴被XChinux在2005-09-22 23:02重新编辑 ]
离线wonder
只看该作者 1楼 发表于: 2005-09-22
你说的乱码是指的“中文测试”这四个字??
离线tasteprogram
只看该作者 2楼 发表于: 2005-09-22
是的,一到服务器那边就是乱码
离线XChinux

只看该作者 3楼 发表于: 2005-09-22
服务器收到的是经过base64编码的字符,你需要进行解码。同样,你在收到它的返回的时候也是那样的。也需要进行解码
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线tasteprogram
只看该作者 4楼 发表于: 2005-09-23
您的意思是不是让我在QT客户端把url进行base64编码,然后发送出去,浏览器会自动进行解码?那么在base64编码之前我还用不用进行GBK转换?
谢谢!
离线tasteprogram
只看该作者 5楼 发表于: 2005-09-23
还有我在IE中直接键入url地址,即http://localhost/info.php?message=中文测试 ,并没有问题。可是把这个url用客户端去发“中文测试”总是乱码。
请问,IE中是如何把url进行编码的。我的代码还需要改动什么?

谢谢
离线XChinux

只看该作者 6楼 发表于: 2005-09-23
在发送的时候要进行编码,在收到的时候要进行解码。
另外,因为你使用的是QT系统,所以HTTP的文件的编码要使用UTF8,这样就省事多了。要不然,你还得要在UTF8和GBK之间转换
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线XChinux

只看该作者 7楼 发表于: 2005-09-23
那是因为浏览器在发送的时候自动把中文进行编码了。
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线tasteprogram
只看该作者 8楼 发表于: 2005-09-23
我叙述一边发送请求的过程吧,还请XChinux 大侠指点。
首先我要对http头进行base64编码,由于QString 是unicode编码,所以我要进行从unicode到UTF8转换,如果网页那边的字符集是gb2312的话,我还要进行从utf8到gbk的转换。

在我接收到http服务器发来的回应时要进行base64解码。



请XChinux 大侠赐教!谢谢大家!复函为盼!
离线XChinux

只看该作者 9楼 发表于: 2005-09-23
这是我以前写过的一个关于发送和接收HTTP数据的一个C#函数
strPostData是已经经过HttpUtility.UrlEncode(strTemp, Encoding.GetEncoding(siteInfo.strEncode))进行编码过的数据(以&连接起来的)

    public bool Post(string strRequestUrl, string strPostData, string strReferer, string strEncode, string strResponseUrl, string strResponseText)
        {
              HttpWebRequest request = (HttpWebRequest)WebRequest.Create(strRequestUrl);
              request.CookieContainer = cookie;
              request.Referer = strReferer;
              request.ContentType = "application/x-www-form-urlencoded";
              request.ContentLength = strPostData.Length;
              request.Method = "POST";
              StreamWriter writer = new StreamWriter(request.GetRequestStream());
              writer.Write(strPostData);
              writer.Close();
              HttpWebResponse response = (HttpWebResponse)request.GetResponse();
              StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(strEncode));
              bool ret = (response.ResponseUri.AbsoluteUri.CompareTo(strResponseUrl) >= 0 && reader.ReadToEnd().IndexOf(strResponseText) >= 0);
              reader.Close();
              response.Close();
              return ret;
        }
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线tasteprogram
只看该作者 10楼 发表于: 2005-09-25
谢谢大家的指点,程序已经可以发送中文了。具体的代码如下:
void SMWSMainWindowImpl::sendinfo()
{
     QString httpmsg,msg;

     smess_tb->append("         "+QTime::currentTime().toString("hh:mm:ss")+"\n");
     tcpdialog->connToHost();

     QTextCodec *codec = QTextCodec::codecForName("utf8");
     msg = codec->toUnicode(mess_te->text().local8Bit());
     QUrl *qurl = new QUrl();
     qurl->encode(msg);
     httpmsg = "GET "+param+"?message="+msg+" HTTP/1.1\r\nHost:\r\nAccept:*/*\r\nUser-Agent:Mozilla/4.0\r\n\r\n";
     smess_tb->append(httpmsg.latin1());
     tcpdialog->sendPacket(httpmsg.latin1(),httpmsg.length());
//      tcpdialog->closeConnection();
}

可是又遇到了新的问题,有时安装这个程序的机器是无法访问到internet的,我们的业务机也要求不能挂在外网上。所以需要一个能够访问internet的机器作为代理,来把这个程序发送的信息再转发到目的地。我打算在一个能够访问internet的机器上装apache服务器,然后在写一个后台程序(*.php)在做中转,我觉得这个方法是可行的。在测试中,中转程序(*.php)可以接收到这个应用发来的信息,可是在中转程序重定向时就有问题了。我试了两中代码。
第一个代码是
<?php
Header("Location: http://xxxxx.com.cn/asp/send.asp?message=".$message);
?>
第二个代码是
<?php
Header("GET /asp/send.asp?message=123 HTTP/1.1");
Header("Host:xxxxx.com.cn");
Header("Accept:*/*");
Header("User-Agent:Mozilla/4.0");
?>
可这两段代码都不能正常的中转,请各位大侠帮我看看我的中转程序(*.php)有什么问题,是不是还缺了什么。谢谢! 复函为盼!
离线XChinux

只看该作者 11楼 发表于: 2005-09-25
不用写PHP文件,直接在Apache下配置个ProxyPass就行了.
详情看这个帖子:
http://www.qtcn.org/bbs/read.php?tid=292
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线tasteprogram
只看该作者 12楼 发表于: 2005-09-26
谢谢大侠的指点,不胜感激!已经实验成功!

可是上面的代码我始终弄不明白为什么不能转发,通过header发送http头这个方法我觉得绝对可行,是不是少了必须要填写的http头项呢?我会继续实验的。如果哪位大侠清楚,还请赐教。

谢谢!复函为盼!
离线XChinux

只看该作者 13楼 发表于: 2005-09-26
你的PHP代码第一个是把它转向到另一个网址了,而那个网址内网访问不到,是没用的,起不了作用.
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线tasteprogram
只看该作者 14楼 发表于: 2005-09-26
大侠可能还没有了解我的意思。我的那个http客户端(用qt写的那个应用)要给一个在internet上的web服务器发送请求,这个客户端要放在业务机上运行。可是有的时候,业务机是不能挂在internet上的,所以就需要用一个可以访问internet的机器来做中转。我在一个可以访问internet的机器中安装了apache服务器,用来将从http客户端发来的请求再中转到目标web服务器上。

现在中转程序,也就是我的那两段php代码,可以正常接收来自http客户端发来的请求(中文也可以了),可是就是在重定向的时候有问题。因为我那个目标服务器是个短信服务器,如果成功会给我发送短信息。可以试了很多遍都没有发送短信过来,所以我就断定中转程序并没有给我中转成功。

使用在apache添加proxypass等属性,就成功了。
离线XChinux

只看该作者 15楼 发表于: 2005-09-26
是这样的,你用header函数转到那个本来是要qt程序访问的网址上,实际上就等于你直接用qt访问那个网址,所以是行不通的.
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线tasteprogram
只看该作者 16楼 发表于: 2005-09-26
您能说的再详细点吗?我的中转程序可是在另外一台机器上呀,是可以访问外网的,从http客户端接收到请求消息,然后在重定向到目标服务器,为什么说就等于是http客户端访问一样呢?我觉得这样就等于是中转机在向目标服务器发请求,只不过请求的内容是从http客户端来的呀!
离线XChinux

只看该作者 17楼 发表于: 2005-09-26
header()是转移了,但人家是返回去qt机器了,而不是返回到代理机器再从代理机器返回到qt机器.
二笔 openSUSE Vim N9 BB10 XChinux@163.com 网易博客 腾讯微博
承接C++/Qt、Qt UI界面、PHP及预算报销系统开发业务
离线tasteprogram
只看该作者 18楼 发表于: 2005-09-26
我明白您的意思了,就是说header只是用来转移请求,并不根据自己的环境来发送相关信息给指定的url,对吗?

那我的第二段代码应该就是根据自己的环境来发送head头吧?我再试试吧,谢谢大侠!
快速回复
限100 字节
 
上一个 下一个