• URL参数编码及Request.QueryString遇到“+”时的情况


    今天突然遇到个默名奇妙的现象,参数"id=25"始终无法解析 :

    此前参数传递方式都是:
    客户端:
      //先通过DES加密,再用Encode编码。
      <%# URL.Encode(DES.Encode(Eval("Id").ToString(), DES.SECRET)) %>
    服务器:
      //先通过DES解密,再用Decode编码。
      int.TryParse(URL.Decode(DES.Decode(Request.QueryString["id"], DES.SECRET)), out hotelId);
    PS:URL和DES都是封装的类,直接调用的静态方法。
    单步调试了一下,原来"25"经过加密编码后返回的字符串为:"gkn+7QsXyP8=" 再通过EnCode编码参数就变成了:"gkn%2b7QsXyP8%3d"
    这里面有个很特别的字符"+"!因为,在url中+表示空格,通过Reflector工具调试到UrlDecode内部方法可以很容易的看出这一点,页面底部是调试得来的代码,红色部分写的很清楚。
    此时查看QueryString 可以看到: Request.QueryString = {id=gkn+7QsXyP8%3d}
    执行:Request.QueryString["id"].ToString()后得到的值却是:"gkn 7QsXyP8="。可以看出+变成了空格,%3d变成了= 。
    找到了问题的原因,下面就是解决办法了:Request.QueryString["id"].RePlace(" ","+")。
     
    此外:在url中如果出现特殊字符会有一套处理的规则:使用"%+ASCII值"的形式来替代原字符。
    例如:+ 转换为%2d 、= 转换为%3d 、? 转换为%3f。值得注意的就是在url中+表示空格
    附:UrlDecode反编译后的代码,看得出+的特殊性 
    private static string UrlDecodeStringFromStringInternal(string s, Encoding e)
    {
        int length = s.Length;
        UrlDecoder decoder = new UrlDecoder(length, e);
        for (int i = 0; i < length; i++)
        {
            char ch = s[i];
            //注意这里
            if (ch == '+')
            {
                ch = ' ';
            }
            else if ((ch == '%') && (i < (length - 2)))
            {
                if ((s[i + 1] == 'u') && (i < (length - 5)))
                {
                    int num3 = HexToInt(s[i + 2]);
                    int num4 = HexToInt(s[i + 3]);
                    int num5 = HexToInt(s[i + 4]);
                    int num6 = HexToInt(s[i + 5]);
                    if (((num3 < 0) || (num4 < 0)) || ((num5 < 0) || (num6 < 0)))
                    {
                        goto Label_0106;
                    }
                    ch = (char) ((((num3 << 12) | (num4 << 8)) | (num5 << 4)) | num6);
                    i += 5;
                    decoder.AddChar(ch);
                    continue;
                }
                int num7 = HexToInt(s[i + 1]);
                int num8 = HexToInt(s[i + 2]);
                if ((num7 >= 0) && (num8 >= 0))
                {
                    byte b = (byte) ((num7 << 4) | num8);
                    i += 2;
                    decoder.AddByte(b);
                    continue;
                }
            }
        Label_0106:
            if ((ch & 0xff80) == 0)
            {
                decoder.AddByte((byte) ch);
            }
            else
            {
                decoder.AddChar(ch);
            }
        }
        return decoder.GetString();
    }
    
  • 相关阅读:
    (6)在树莓派上截屏的方法
    (7)树莓派读物USB摄像头
    (4)给树莓派安装中文输入法Fcitx及Google拼音输入法
    (3)使用Android手机作为树莓派的屏幕
    (2)在树莓派安装运行在Python3上的OpenCV
    相机靶面尺寸和视场角换算
    STM32F103C8T6在Arduino IDE里编程
    项目(二) esp32-cam 网页图像人脸
    开发(一) ardunio环境配置 针对esp32-cam 更多例程
    [转] Compile、Make和Build的区别
  • 原文地址:https://www.cnblogs.com/wadeheng/p/1920936.html
Copyright © 2020-2023  润新知