kbmMWEncodeEscapes 中汉字编码的问题及解决办法

时间:2023-03-09 06:00:14
kbmMWEncodeEscapes 中汉字编码的问题及解决办法

kbmMWEncodeEscapes 是kbmmw 里面的一个函数,用来对URL 中的汉字进行编码,例如

http://127.0.0.1/getname?name=春节,由于'春节'是汉字,浏览器向台发送请求时,会把这个连接转会为

http://127.0.0.1/getdata?name=%B4%BA%BD%DA

而kbmMWEncodeEscapes 就是实现转换的函数,但是由于D2009 以后,delphi 支持unicode。导致kbmMWEncodeEscapes

在转换汉字时出现问题,不能正常转换。

因此需要修改,经过修改后代码变成以下:

function kbmMWEncodeEscapes(const AString:string):string;
var
i,l:integer;
sb:TkbmMWStringBuilder;
B: TBytes;
begin
B:=TEncoding.ANSI.GetBytes(AString);
sb:=TkbmMWStringBuilder.Create;
try
l:=Length(b);
for i:=0 to (l-1) do
begin
if chr(b[i])=' ' then
begin
sb.Append('+');
continue;
end;
if not (chr(b[i]) in ['a'..'z', 'A'..'Z', '0'..'9', '_']) then
begin
sb.Append('%'+IntToHex(Ord(B[I]),2));
continue;
end;
sb.Append(chr(b[i]));
end;
Result:=sb.ToString;
finally
sb.Free;
end;
end;

同样,由于解码函数也要进行相应的变化

function kbmMWDecodeEscapes(const AString:string):string;
var
i,k,l:integer;
B: TBytes;
begin
l:=Length(AString);
if l<=0 then
begin
Result:='';
exit;
end;
setlength(b,l);
i:=1;
k:=0;
repeat
if AString[i]='+' then
begin
b[k]:=ord(' ');
inc(i);
inc(k);
end
else if AString[i]='%' then
begin
b[k]:=(Hex2Dec[ord(AString[i+1]) and $1F] shl 4)
+Hex2Dec[ord(AString[i+2]) and $1F];
inc(i,3);
inc(k);
end
else
begin
b[k]:=ord(AString[i]);
inc(i);
inc(k);
end;
until i>l;
setlength(b,k); result:=TEncoding.ANSI.GetString(b); end;

其实,以上的转换是把汉字转换成对应windows codepage 的ansic 码值,为了更通用的目的

可以使用以下函数进行编码:

function URIEncode(const S: string ; Encoding : TEncoding): string;
cURLUnreservedChars = ['A'..'Z', 'a'..'z', '0'..'9', '-', '_', '.', '~'];
var
I: Integer;
B: TBytes;
begin
result:='';
B:=Encoding.GetBytes(S);
for I := Low(B) to High(B) do
begin
if CharInSet(Chr(B[I]), cURLUnreservedChars) then
Result:=Result+WideChar(B[I]) else
Result:=Result+'%'+IntToHex(Ord(B[I]),2);
end;
end;

这个函数,你可以对 string 进行各种编码。以适合程序的应用。