近期在做网址编码相关的工作,发现在用 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. linux df -h卡成狗

    linux执行df -h命令,直接卡在,很久没有任何动静 strace df -h跟踪命令执行,查看卡在那里 还有可能就是重做系统吧,检测下内存条是不是坏了等 http://blog.51cto.co ...

  2. 七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递 【转】

    http://www.cnblogs.com/powertoolsteam/p/MVC_two.html 通过第一天的学习之后,我们相信您已经对MVC有一些基本了解. 本节所讲的内容是在上节的基础之上 ...

  3. breakpoints &amp;&amp; lldb &#160;&amp;&amp; chisel 的使用

    Breakpoints BreakPoint分类 breakpoint也是有分类的.我这里的文章内大致按使用的方式分为了 Normal Breakpoint,Exception Breakpoint, ...

  4. 深入解析Windows窗体创建和消息分发

    Windows GUI採用基于事件驱动的编程模型,其实差点儿全部的界面库都是这样做的.在纯粹的Window32 SDK编程时代.人们还能够搞懂整个Windows窗口创建和消息的流通过程.可是在如今各种 ...

  5. hdu 2814 Interesting Fibonacci

    pid=2814">点击此处就可以传送 hdu 2814 题目大意:就是给你两个函数,一个是F(n) = F(n-1) + F(n-2), F(0) = 0, F(1) = 1; 还有 ...

  6. Mysql或者Hive数据行变成列

    对于mysql /  hive 再进行统计的时候假设须要行变成列,能够使用函数 CASE 字段a WHEN 值b THEN c [WHEN d THEN e]* [ELSE f] END 当字段a=值 ...

  7. [Android Studio 权威教程]最有用的快捷键

    上篇中我们讲了Android Studio怎样加入插件.这篇我们讲讲AS的快捷键.这里我说明的快捷键都是最最有用的,希望刚刚加入AS的朋友尽快的熟悉一下这几个快捷键,这样能够帮助你提高coding的效 ...

  8. c#中Monitor的使用

    首先lock和Minitor有什么区别呢? 其实lock在IL代码中会被翻译成Monitor.也就是Monitor.Enter(obj)和Monitor.Exit(obj). lock(obj) { ...

  9. log4j:WARN Please initialize the log4j system properly.

    在tomcat启动的时候,出现这个警告: log4j:WARN No appenders could be found for logger (org.apache.commons.digester. ...

  10. centos 6.9 x86 安装搭建hadoop集群环境

    又来折腾hadoop了 文件准备: centos 6.9 x86 minimal版本 163的源 下软件的时候可能会用到 jdk-8u144-linux-i586.tar.gz ftp工具 putty ...