【问题标题】:No mapping for the Unicode character exists in the target multi-byte code page目标多字节代码页中不存在 Unicode 字符的映射
【发布时间】:2017-03-21 21:37:17
【问题描述】:

我有一个用 Delphi 2007 构建的肥皂,它可以工作!

在 Delphi 10.1 Berlin 进行转换后,我有很多例外:

目标多字节代码页中不存在 Unicode 字符的映射

原因似乎,当 webbroker HttpApp 解析请求参数时,如果请求在查询字符串中有一些 url 编码的字符,则会引发此异常,例如:

http://localhost/soap/soap.dll/action?param=%E0

事实上,如果我用%E0 (à url encoded) 打电话给URL.Decode()

TNetEncoding.URL.Decode('%E0');

它引发了同样的异常:

目标多字节代码页中不存在 Unicode 字符的映射

问题出现在方法TURLEncoding.DoDecode(const Input: string): string 上的单元System.NetEncoding。此方法尝试仅在 UTF-8 中转换 url 编码的字符,而不对Windows-1252 进行任何回退。字符串%E0à 的Windows-1252 编码,但delphi 只能转换UTF-8 版本:%C3%A0

一个小的(不完美,不优雅)修复是添加一个后备:

try
  Result := TEncoding.UTF8.GetString(Bytes); // original Delphi 10.1 line
except
  on E: EEncodingError do Result := string(PChar(Bytes)); // fallback
end;

完整代码:

function TURLEncoding.DoDecode(const Input: string): string;

  function DecodeHexChar(const C: Char): Byte;
  begin
    case C of
       '0'..'9': Result := Ord(C) - Ord('0');
       'A'..'F': Result := Ord(C) - Ord('A') + 10;
       'a'..'f': Result := Ord(C) - Ord('a') + 10;
    else
      raise EConvertError.Create('');
    end;
  end;

  function DecodeHexPair(const C1, C2: Char): Byte; inline;
  begin
    Result := DecodeHexChar(C1) shl 4 + DecodeHexChar(C2)
  end;

var
  Sp, Cp: PChar;
  I: Integer;
  Bytes: TBytes;

begin
  SetLength(Bytes, Length(Input) * 4);
  I := 0;
  Sp := PChar(Input);
  Cp := Sp;
  try
    while Sp^ <> #0 do
    begin
      case Sp^ of
        '+':
          Bytes[I] := Byte(' ');
        '%':
          begin
            Inc(Sp);
            // Look for an escaped % (%%)
            if (Sp)^ = '%' then
              Bytes[I] := Byte('%')
            else
            begin
              // Get an encoded byte, may is a single byte (%<hex>)
              // or part of multi byte (%<hex>%<hex>...) character
              Cp := Sp;
              Inc(Sp);
              if ((Cp^ = #0) or (Sp^ = #0)) then
                raise EHTTPException.CreateFmt(sErrorDecodingURLText, [Cp - PChar(Input)]);
              Bytes[I] := DecodeHexPair(Cp^, Sp^)
            end;
          end;
      else
        // Accept single and multi byte characters
        if Ord(Sp^) < 128 then
          Bytes[I] := Byte(Sp^)
        else
          I := I + TEncoding.UTF8.GetBytes([Sp^], 0, 1, Bytes, I) - 1

      end;
      Inc(I);
      Inc(Sp);
    end;
  except
    on E: EConvertError do
      raise EConvertError.CreateFmt(sInvalidURLEncodedChar, [Char('%') + Cp^ + Sp^, Cp - PChar(Input)])
  end;
  SetLength(Bytes, I);

  // ------> MY FIX <------
  try
     Result := TEncoding.UTF8.GetString(Bytes); // Original line
  except
     on E: EEncodingError do Result := string(PChar(Bytes));
  end;
  // END FIX
end;

经过大量搜索,我找到了Bug fix list for RAD Studio 10.1 Berlin,它说这个错误已修复:

Webbroker HttpApp 解析请求参数并收到错误“目标多字节代码页中不存在 Unicode 字符的映射”

但不适合我...

【问题讨论】:

  • 仅供参考,没有 Delphi XE 10.1 这样的东西 - 它只是 Delphi 10.1 Berlin。更新了您的标签。

标签: delphi utf-8 urlencode delphi-10.1-berlin webbroker


【解决方案1】:

尝试使用 WEB.ReqMulti;

当表单中有多字节字符时,当我使用 WebBroker 处理来自网页的 POST 方法时,我遇到了同样的异常。

而我在WebBroker的项目中添加了use WEB.ReqMulti后,这个异常就消失了。

【讨论】:

    【解决方案2】:

    尝试关闭 IDE 时,我在 Tokyo (10.2.1) IDE 中出现“目标多字节代码页中不存在 Unicode 字符的映射”异常。 修复:从项目目录中删除文件 .$$$。

    【讨论】:

      猜你喜欢
      • 2013-08-14
      • 2014-08-05
      • 2014-11-21
      • 1970-01-01
      • 2014-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-13
      相关资源
      最近更新 更多