近期在做网址编码相关的工作,发现在用 XE5 编译的时候,一切正常,拿 到 XE7下 就 结果错误了。百度了下,谷歌 了下,有人提出,但是,我没有找到答案,也许都没有碰到这个问题,也许都己经自己默默的解决了,在此 小记一下,方便后人,也方便自己 查寻。

例子 : 原字符   "过年"

httpencode('过年') 结果 :

XE5为  %B9%FD%C4%EA

XE7 调用 相当函数结果 %E8%BF%87%E5%B9%B4

百思不得其解啊,折腾了很长时间,后来终于想到是不是 此函数 官方更新修改了,(没办法,人比较笨)

于是查看源码:

XE5的 web.httpapp 中(分string 和 ansistring, 我用ansistring 版本得到 期望的结果):

 function HTTPEncode(const AStr: string): string;
// The NoConversion set contains characters as specificed in RFC 1738 and
// should not be modified unless the standard changes.
const
NoConversion = [Ord('A')..Ord('Z'), Ord('a')..Ord('z'), Ord('*'), Ord('@'),
Ord('.'), Ord('_'), Ord('-'), Ord('')..Ord(''), Ord('$'),
Ord('!'), Ord(''''), Ord('('), Ord(')')];
var
Sp, Rp: PChar;
begin
SetLength(Result, Length(AStr) * );
Sp := PChar(AStr);
Rp := PChar(Result);
while Sp^ <> # do
begin
if Ord(Sp^) in NoConversion then
Rp^ := Sp^
else
if Sp^ = ' ' then
Rp^ := '+'
else
begin
FormatBuf(Rp, , string('%%%.2x'), , [Ord(Sp^)]);
Inc(Rp,);
end;
Inc(Rp);
Inc(Sp);
end;
SetLength(Result, Rp - PChar(Result));
end; function HTTPDecode(const AStr: string): string;
var
Sp, Rp, Cp: PChar;
S: string;
begin
SetLength(Result, Length(AStr));
Sp := PChar(AStr);
Rp := PChar(Result);
Cp := Sp;
try
while Sp^ <> # do
begin
case Sp^ of
'+': Rp^ := ' ';
'%': begin
// Look for an escaped % (%%) or %<hex> encoded character
Inc(Sp);
if Sp^ = '%' then
Rp^ := '%'
else
begin
Cp := Sp;
Inc(Sp);
if (Cp^ <> #) and (Sp^ <> #) then
begin
S := Char('$') + Cp^ + Sp^;
Rp^ := Char(StrToInt(string(S)));
end
else
raise EWebBrokerException.CreateFmt(sErrorDecodingURLText, [Cp - PChar(AStr)]);
end;
end;
else
Rp^ := Sp^;
end;
Inc(Rp);
Inc(Sp);
end;
except
on E:EConvertError do
raise EConvertError.CreateFmt(sInvalidURLEncodedChar,
[Char('%') + Cp^ + Sp^, Cp - PChar(AStr)])
end;
SetLength(Result, Rp - PChar(Result));
end; function HTTPEncode(const AStr: AnsiString): AnsiString;
// The NoConversion set contains characters as specificed in RFC 1738 and
// should not be modified unless the standard changes.
const
NoConversion = ['A'..'Z','a'..'z','*','@','.','_','-',
''..'','$','!','''','(',')'];
var
Sp, Rp: PAnsiChar;
begin
SetLength(Result, Length(AStr) * );
Sp := PAnsiChar(AStr);
Rp := PAnsiChar(Result);
while Sp^ <> # do
begin
if Sp^ in NoConversion then
Rp^ := Sp^
else
if Sp^ = ' ' then
Rp^ := '+'
else
begin
System.AnsiStrings.FormatBuf(Rp^, , AnsiString('%%%.2x'), , [Ord(Sp^)]);
Inc(Rp,);
end;
Inc(Rp);
Inc(Sp);
end;
SetLength(Result, Rp - PAnsiChar(Result));
end;

在XE7中

web.httpapp:

function HTTPEncode(const AStr: string): string;
begin
Result := TNetEncoding.URL.Encode(AStr);
end;

查看 system.netencoding

找到

function TNetEncoding.DoEncode(const Input: array of Byte): TBytes;
begin
Result := TEncoding.UTF8.GetBytes(DoEncode(TEncoding.UTF8.GetString(@Input[])));
end;
查看类定义:  
TURLEncoding = class(TNetEncoding)
protected
function DoDecode(const Input: string): string; overload; override;
function DoEncode(const Input: string): string; overload; override;
end;
查看函数代码:
function TURLEncoding.DoEncode(const Input: string): string;
// The NoConversion set contains characters as specificed in RFC 1738 and
// should not be modified unless the standard changes.
const
NoConversion = [Ord('A')..Ord('Z'), Ord('a')..Ord('z'), Ord('*'), Ord('@'),
Ord('.'), Ord('_'), Ord('-'), Ord('')..Ord(''), Ord('$'),
Ord('!'), Ord(''''), Ord('('), Ord(')')]; procedure AppendByte(B: Byte; var Buffer: PChar);
const
Hex = '0123456789ABCDEF';
begin
Buffer[] := '%';
Buffer[] := Hex[B shr + Low(string)];
Buffer[] := Hex[B and $F + Low(string)];
Inc(Buffer, );
end; var
Sp, Rp: PChar;
MultibyteChar: TBytes;
I, ByteCount: Integer;
begin
// Characters that require more than 1 byte are translated as "percent-encoded byte"
// which will be encoded with 3 chars per byte -> %XX
// Example: ?character
// Multibyte representation: C391 (2 bytes)
// URL encode representation: %C3%91
//
// So the worst case is 4 bytes(max) per Char, and 3 characters to represent each byte
SetLength(Result, Length(Input) * * );
Sp := PChar(Input);
Rp := PChar(Result);
SetLength(MultibyteChar, );
while Sp^ <> # do
begin
if Ord(Sp^) in NoConversion then
begin
Rp^ := Sp^;
Inc(Rp)
end
else if Sp^ = ' ' then
begin
Rp^ := '+';
Inc(Rp)
end
else
begin
if (Ord(Sp^) < ) then
// Single byte char
AppendByte(Ord(Sp^), Rp)
else
begin
// Multi byte char
ByteCount := TEncoding.UTF8.GetBytes([Sp^], , , MultibyteChar, );
for I := to ByteCount - do
AppendByte(MultibyteChar[I], Rp);
end
end;
Inc(Sp);
end;
SetLength(Result, Rp - PChar(Result));
end;

似乎有点不同。

目前是我自己建立一个函数 ,复制XE5版本的 代码 放在XE7里面调用,得到希望的结果的。

代码:

function MyHTTPEncode(const AStr: AnsiString): AnsiString;
// The NoConversion set contains characters as specificed in RFC 1738 and
// should not be modified unless the standard changes.
const
NoConversion = ['A'..'Z','a'..'z','*','@','.','_','-',
''..'','$','!','''','(',')'];
var
Sp, Rp: PAnsiChar;
begin
SetLength(Result, Length(AStr) * );
Sp := PAnsiChar(AStr);
Rp := PAnsiChar(Result);
while Sp^ <> # do
begin
if Sp^ in NoConversion then
Rp^ := Sp^
else
if Sp^ = ' ' then
Rp^ := '+'
else
begin
System.AnsiStrings.FormatBuf(Rp^, , AnsiString('%%%.2x'), , [Ord(Sp^)]);
Inc(Rp,);
end;
Inc(Rp);
Inc(Sp);
end;
SetLength(Result, Rp - PAnsiChar(Result));
end;

delphi XE7 HttpEncode 编码问题的更多相关文章

  1. Delphi XE7调用C++动态库出现乱码问题回顾

    事情源于有个客户需使用我们C++的中间件动态库来跟设备连接通讯,但是传入以及传出的字符串指针格式都不正确(出现乱码或是被截断),估计是字符编码的问题导致.以下是解决问题的过程: 我们C++中间件动态库 ...

  2. delphi中httpencode使用注意事项

    delphi中httpencode使用注意事项 一.uses HTTPApp二.使用前要用UTF8Encode转换成utf-8编码HTTPEncode(UTF8Encode(Text));不然和标准的 ...

  3. SynEdit(Delphi XE7)的安装和基本使用

    一.花絮 delphi自带的memo显示sql语句看的太累人了,今天决定美化一下.最起码要有“语法着色”.“显示行号”这2个功能. 意外发现了 SynEdit 控件. SynEdit是一个免费的文字编 ...

  4. RemObjects SDK Source For Delphi XE7

    原文:http://blog.csdn.net/tht2009/article/details/39545545 1.目前官网最新版本是RemObjects SDK for Delphi and al ...

  5. delphi XE7 中的消息

    在delphi XE7的程序开发中,消息机制保证进程间的通信. 在程序中,消息来自: 1)系统: 通知你的程序用户输入,涂画以及其他的系统范围的事件: 2)你的程序:不同的程序部分之间的通信信息.   ...

  6. 关于delphi XE7中的动态数组和并行编程(第一部分)

    本文引自:http://www.danieleteti.it/category/embarcadero/delphi-xe7-embarcadero/ 并行编程库是delphi XE7中引进的最受期待 ...

  7. 咏南CS多层插件式开发框架支持最新的DELPHI XE7

    DATASNAP中间件: 中间件已经在好几个实际项目中应用,长时间运行异常稳定,可无人值守: 可编译环境:DELPHI XE5~DELPHI XE7,无需变动代码: 支持传统TCP/IP方式也支持RE ...

  8. Delphi XE7中新并行库

    Delphi XE7中添加了新的并行库,和.NET的Task和Parellel相似度99%. 详细内容能够看以下的文章: http://www.delphifeeds.com/go/s/119574 ...

  9. Delphi XE7下如何创建一个Android模拟器调试

    利用Delphi XE7我们可以进行多种设备程序的开发,尤其是移动开发应用程序得到不断地加强.在实际的Android移动程序开发中,如果我们直接用android真机直接调试是非常不错.一是速度快,二是 ...

随机推荐

  1. 140. Word Break II(hard)

    欢迎fork and star:Nowcoder-Repository-github 140. Word Break II 题目: Given a non-empty string s and a d ...

  2. MAT使用及OOM分析

    知识及工具推荐 1.Android资源监控工具 2.Android内存管理机制 http://blog.csdn.net/hexieshangwang/article/details/47188987

  3. TP框架模板中ifelse

    {if $_username}<ul class="afterLogin">    <li class="username"><a ...

  4. ORACLE数据库导表

    今天在公司的server上面装一个系统,在数据库导表的时候一直导不进去,原先是10g的.dmp文件,导入11g.怀疑版本号不兼容,后来把.dmp表打开,把里面的版本号号改为11g,发现导入还是不行.i ...

  5. merge-sorted-array——合并两个有序数组

    Given two sorted integer arrays A and B, merge B into A as one sorted array. Note: You may assume th ...

  6. javascript Math函数

    Math.max().作用:返回参数里的数字里最大的一个数字: Math.max(12,123,3,2,433,4); // returns 433 因为这个函数能够校验数字,并返回其中最大的一个,所 ...

  7. Cardboard虚拟现实开发初步(一)

    Google Cardboard 虚拟现实眼镜开发初步(一) 虚拟现实技术简单介绍 不得不说这几年虚拟现实技术逐渐火热,伴随着虚拟现实设备的价格迅速平民化,越来越多的虚拟现实设备来到了我们眼前,也因此 ...

  8. NSTimer使用不当引发的内存泄漏问题

    NSTimer可以用来执行一些定时任务,比较常用的方法就是: + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTar ...

  9. win10+vs2017+asp.net MVC5+EF6+mysql 闪退问题,解决方法

    1.安装 mysql-for-visualstudio-2.0.5.msi 2.安装 mysql-connector-net-6.10.7.msi 3.在VS2017 右键选中项目,管理NuGet程序 ...

  10. Enumerate Combination C(k, n) in a bitset

    Suppose n<=32, we can enumerate C(k, n), with bits representing absence or presence, in the follo ...