近期在做网址编码相关的工作,发现在用 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. 对ps4 cmask fmask的理解

    这俩都是绑在corlor target上8x8的格子 cmask 做fastclear 这个比较好理解,8x8来表示这个格子是否clear fmask msaa用 provided to suppor ...

  2. hbase安装配置

    环境准备 Java HDFS zookeeper SSH,NTP时间同步 系统调优,这个可以等安装完后改,文件打开数(ulimit和nproc) 修改Hadoop HDFS Datanode同时处理文 ...

  3. Android设计模式之中的一个个样例让你彻底明确装饰者模式(Decorator Pattern)

    导读 这篇文章中我不会使用概念性文字来说明装饰者模式.由于通常概念性的问题都非常抽象.非常难懂.使得读者非常难明确究竟为什么要使用这样的设计模式.我们设计模式的诞生,肯定是前辈们在设计程序的时候遇到了 ...

  4. Shell脚本之:for

    与其他编程语言类似,Shell支持for循环. for循环一般格式为: for 变量 in 列表 do command1 command2 ... commandN done 列表是一组值(数字.字符 ...

  5. eclipse学习

    网上转载,以作以后学习之用! eclipse学习 关键字: eclipse学习 1 eclipse插件安装方法(link方法) 一般插件包含一个eclipse目录,其下是features和plugin ...

  6. spring-struts-mybatis整合错误集锦

    尽管三大框架特别特别的好用,可是,当我第一次把这三个框架用maven整合到一起的时候.各种错误接踵而至,以下来做一下三大框架整合的总结: 首先是在导入三大框架的各种依赖包的时候,由于我用的是j2ee  ...

  7. 27:简单错误记录SimpleErrorLog

    题目描述 开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号. 处理: 1. 记录最多8条错误记录,循环记录,对相同的错误记录(净文件名称和行号完全匹配)只记录一条,错误计数增加: ...

  8. CentOS开启FTP及配置用户

    vsftpd作为FTP服务器,在Linux系统中是非常常用的.下面我们介绍如何在centos系统上安装vsftp. 什么是vsftpd vsftpd是一款在Linux发行版中最受推崇的FTP服务器程序 ...

  9. Flex版的2048游戏

    近期2048游戏好像挺火.在公交,吃饭,甚至在路上走路都有人拿着手机在玩,之前我看同事玩,认为非常幼稚,移来移去太无聊了吧 到后面自己也下了.发现确实挺无聊的,也就是在无聊的时候打发无聊的时间,后来就 ...

  10. 使用Docker开发NodeJs APP

    英文版原文地址 这是两篇连载文章的第一篇,讲解了如何使用 Docker 替代 Vagrant 开发基于 Express 框架的NodeJs App的部分细节.不过,这次要增加点难度:我们要使用 con ...