您的位置:首页 > 理论基础 > 计算机网络

c++encode http请求带中文参数

2015-08-24 10:38 716 查看
我们前端是C++的,服务器是java的,传输的数据需要encode编码和decode解码。碰到的问题就是http网络请求带中文参数时(我们传的是玩家姓名),服务器接到的参数和我传过去的是不一致的。这就需要处理带中文参数的问题。

前端传过去的:content=eyJ1aWQiOiJsYWxhMTEiLCJnYW1laWQiOiIxMDAxIiwicGxheWVybmFtZSI6IumrmOWkp+Wco+iQveiQvSIsInBsYXllcnNleCI6MCwicGxheWVyaW1hZ2UiOjEwMDR9&sign=ff595ba32a2dd04d8344cf5d86788293

服务器收到的:content====eyJ1aWQiOiJsYWxhMTEiLCJnYW1laWQiOiIxMDAxIiwicGxheWVybmFtZSI6IumrmOWkp Wco iQveiQvSIsInBsYXllcnNleCI6MCwicGxheWVyaW1hZ2UiOjEwMDR9

+变成了空格。

java那边可以在传的时候加上编码格式:String encodeAfter = URLEncoder.encode(“conteng”, "utf-8");但是c++里没有这个方法。于是在网上找了一下,发现有可以支持不管带不带中文都可以的encode代码。但是这样编码之后是这样的%7B%22uid%22%3A%22lala11%22%2C%22gameid%22%3A%221001%22%2C%22channelid%22%3A%22PopStar3_360%22%7D,服务器那边说解析不了,于是我就在java上新建个测试类,代码如下:

        String test = "{\"uid\":\"lala11\",\"gameid\":\"1001\",\"playername\":\"开心的笑笑\",\"playersex\":0,\"playerimage\":1005}";

        System.out.println("test:"+test);

        try {

            String encodeAfter = URLEncoder.encode(test, "utf-8");//utf-8"

            System.out.println("encodeAfter:"+encodeAfter);

            String test1 = "%7B%22uid%22%3A%22lala11%22%2C%22gameid%22%3A%221001%22%2C%22channelid%22%3A%22PopStar3_360%22%7D";

            String decodeAfter = URLDecoder.decode(test1, "utf-8");//utf-8"

            System.out.println("test1:"+test1);

            System.out.println("decodeAfter:"+decodeAfter);

        } catch (UnsupportedEncodingException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

经测试通过URLEncoder.encode(test, "utf-8");//utf-8"编码后也是%7B%22uid%22%3A%22lala11%22%2C%22gameid%22%3A%221001%22%2C%22channelid%22%3A%22PopStar3_360%22%7D格式的,并且通过URLDecoder.decode(test1, "utf-8");//utf-8"解码后是完全正确的信息。

后来才发现服务器在解码的时候没用URLDecoder.decode(test1, "utf-8");//utf-8",也是醉了..

好,总结一下就是:C++用新的encode和decode代码,让服务器用URLDecoder.decode(test1, "utf-8");来解码,若需要MD5对比内容,服务器也需用URLEncoder.encode(test, "utf-8");//utf-8"来编码。

C++端的encode和decode代码如下:

.h:

#include <assert.h>

////////////////////解决传输中文问题的编码///////////////////////////////////

static const char safe[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 

std::string encode(const std::string &uri);

std::string decode(const std::string &uri);

.cpp:

#include <iostream>

using namespace std;

std::string encode(const std::string &uri)  

{  

    string ret;   

    const unsigned char *ptr = (const unsigned char *)uri.c_str();  

    ret.reserve(uri.length());  

    for (; *ptr ; ++ptr)  

    {  

        if (!safe[*ptr])   

        {  

            char buf[5];  

            memset(buf, 0, 5);  

#ifdef WIN32  

            _snprintf_s(buf, 5, "%%%X", (*ptr));  

#else  

            snprintf(buf, 5, "%%%X", (*ptr));  

#endif  

            ret.append(buf);      

        }  

        else if (*ptr==' ')  

        {  

            ret+='+';  

        }  

        else{  

            ret += *ptr;  

        }  

    }  

    return ret;  

}  

std::string decode(const std::string &uri)  

{  

    //Note from RFC1630:  "Sequences which start with a percent sign  

    //but are not followed by two hexadecimal characters (0-9,A-F) are reserved  

    //for future extension"  

    const unsigned char *ptr = (const unsigned char *)uri.c_str();  

    string ret;  

    ret.reserve(uri.length());  

    for (; *ptr; ++ptr)  

    {  

        if (*ptr == '%')  

        {  

            if (*(ptr + 1))  

            {  

                char a = *(ptr + 1);  

                char b = *(ptr + 2);  

                if (!((a >= 0x30 && a < 0x40) || (a >= 0x41 && a < 0x47))) continue;  

                if (!((b >= 0x30 && b < 0x40) || (b >= 0x41 && b < 0x47))) continue;  

                char buf[3];  

                buf[0] = a;  

                buf[1] = b;  

                buf[2] = 0;  

                ret += (char)strtoul(buf, NULL, 16);  

                ptr += 2;  

                continue;  

            }  

        }  

        if (*ptr=='+')  

        {  

            ret+=' ';  

            continue;  

        }  

        ret += *ptr;  

    }  

    return ret;  

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ encode http 中文 参数