You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用TNetEncoding.URL.Decode()解码URL时出现Unicode编码映射错误求助

解决TNetEncoding.URL.Decode()的编码映射错误问题

这个错误的核心原因是你的URL参数里的folder=%F6%E7是用GBK/GB2312编码生成的,而TNetEncoding.URL.Decode默认采用UTF-8编码来解码这些百分号转义的字节,导致无效的字节序列无法映射到Unicode字符,从而抛出No mapping for the Unicode character exists in the target multi-byte code page错误。

解决方案1:使用Indy的TIdURI.URLDecode(推荐,更灵活)

如果你的项目已经引用了Indy组件,可以直接用TIdURI.URLDecode方法,它支持指定解码时使用的字符编码,完美适配这种非UTF-8的URL参数场景:

var
  Str: TStringList;
  DecodedFolder: string;
begin
  Str := TStringList.Create;
  try
    // 先处理QueryParams的&替换,拆分参数
    Str.Text := StringReplace(ARequestInfo.QueryParams, '&', #13, [rfReplaceAll]);
    // 单独提取folder参数,用GBK编码解码
    DecodedFolder := TIdURI.URLDecode(Str.Values['folder'], IndyTextEncoding(TEncoding.GetEncoding('GBK')));
    // 其他参数如果是标准UTF-8编码,直接用TNetEncoding.URL.Decode处理即可
    // 比如:var decodedMin := TNetEncoding.URL.Decode(Str.Values['min']);
  finally
    Str.Free;
  end;
end;

解决方案2:手动解码folder参数(不依赖第三方组件)

如果不想引入Indy组件,可以手动实现一个支持指定编码的URL解码函数,把百分号转义的字符串转为字节数组,再用目标编码转成Unicode字符串:

function URLDecodeWithEncoding(const AEncodedStr: string; AEncoding: TEncoding): string;
var
  Bytes: TBytes;
  I: Integer;
  HexStr: string;
begin
  Bytes := [];
  I := 1;
  while I <= Length(AEncodedStr) do
  begin
    if AEncodedStr[I] = '%' then
    begin
      if I + 2 <= Length(AEncodedStr) then
      begin
        HexStr := Copy(AEncodedStr, I + 1, 2);
        try
          SetLength(Bytes, Length(Bytes) + 1);
          Bytes[High(Bytes)] := StrToInt('$' + HexStr);
        except
          // 处理无效转义字符,这里用?替代,可根据需求调整
          SetLength(Bytes, Length(Bytes) + 1);
          Bytes[High(Bytes)] := Ord('?');
        end;
        Inc(I, 3);
      end
      else
      begin
        // 不完整的转义,直接保留原字符
        SetLength(Bytes, Length(Bytes) + 1);
        Bytes[High(Bytes)] := Ord(AEncodedStr[I]);
        Inc(I);
      end;
    end
    else if AEncodedStr[I] = '+' then
    begin
      // URL中+代表空格,替换成空格字节
      SetLength(Bytes, Length(Bytes) + 1);
      Bytes[High(Bytes)] := Ord(' ');
      Inc(I);
    end
    else
    begin
      // 普通字符直接转为字节
      SetLength(Bytes, Length(Bytes) + 1);
      Bytes[High(Bytes)] := Ord(AEncodedStr[I]);
      Inc(I);
    end;
  end;
  Result := AEncoding.GetString(Bytes);
end;

// 调用示例
var
  Str: TStringList;
  DecodedFolder: string;
begin
  Str := TStringList.Create;
  try
    Str.Text := StringReplace(ARequestInfo.QueryParams, '&amp;', #13, [rfReplaceAll]);
    // 用GBK编码解码folder参数
    DecodedFolder := URLDecodeWithEncoding(Str.Values['folder'], TEncoding.GetEncoding('GBK'));
    // 其他参数按需求处理
  finally
    Str.Free;
  end;
end;

额外注意点

  • 一定要确认URL参数的原始编码:中文环境下很多旧系统会用GBK/GB2312编码URL参数,而非标准UTF-8,必须匹配编码才能正确解码。
  • 尽量避免直接用TNetEncoding.URL.Decode处理整个QueryParams,拆分后单独处理特殊编码的参数更稳妥。

内容的提问来源于stack exchange,提问作者serkan güneş

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:23:11