delphi XE7 HttpEncode 编码问题
近期在做网址编码相关的工作,发现在用 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 编码问题的更多相关文章
- Delphi XE7调用C++动态库出现乱码问题回顾
事情源于有个客户需使用我们C++的中间件动态库来跟设备连接通讯,但是传入以及传出的字符串指针格式都不正确(出现乱码或是被截断),估计是字符编码的问题导致.以下是解决问题的过程: 我们C++中间件动态库 ...
- delphi中httpencode使用注意事项
delphi中httpencode使用注意事项 一.uses HTTPApp二.使用前要用UTF8Encode转换成utf-8编码HTTPEncode(UTF8Encode(Text));不然和标准的 ...
- SynEdit(Delphi XE7)的安装和基本使用
一.花絮 delphi自带的memo显示sql语句看的太累人了,今天决定美化一下.最起码要有“语法着色”.“显示行号”这2个功能. 意外发现了 SynEdit 控件. SynEdit是一个免费的文字编 ...
- RemObjects SDK Source For Delphi XE7
原文:http://blog.csdn.net/tht2009/article/details/39545545 1.目前官网最新版本是RemObjects SDK for Delphi and al ...
- delphi XE7 中的消息
在delphi XE7的程序开发中,消息机制保证进程间的通信. 在程序中,消息来自: 1)系统: 通知你的程序用户输入,涂画以及其他的系统范围的事件: 2)你的程序:不同的程序部分之间的通信信息. ...
- 关于delphi XE7中的动态数组和并行编程(第一部分)
本文引自:http://www.danieleteti.it/category/embarcadero/delphi-xe7-embarcadero/ 并行编程库是delphi XE7中引进的最受期待 ...
- 咏南CS多层插件式开发框架支持最新的DELPHI XE7
DATASNAP中间件: 中间件已经在好几个实际项目中应用,长时间运行异常稳定,可无人值守: 可编译环境:DELPHI XE5~DELPHI XE7,无需变动代码: 支持传统TCP/IP方式也支持RE ...
- Delphi XE7中新并行库
Delphi XE7中添加了新的并行库,和.NET的Task和Parellel相似度99%. 详细内容能够看以下的文章: http://www.delphifeeds.com/go/s/119574 ...
- Delphi XE7下如何创建一个Android模拟器调试
利用Delphi XE7我们可以进行多种设备程序的开发,尤其是移动开发应用程序得到不断地加强.在实际的Android移动程序开发中,如果我们直接用android真机直接调试是非常不错.一是速度快,二是 ...
随机推荐
- APNS push server端 SSL3.0 转 TLS (iPhone苹果推送服务)
(转载此文,请说明原文出处) 苹果的官方公布 Update to the Apple Push Notification Service October 22, 2014 The Apple Push ...
- 一次测试岗位针对Java和接口的面试题
1.post和get的区别? 1. get是从服务器上获取数据,post是向服务器传送数据.2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在UR ...
- ThinkPHP 3.1、3.2一个通用的漏洞分析
Author:m3d1t10n 前两天看到phithon大大在乌云发的关于ThinkPHP的漏洞,想看看是什么原因造成的.可惜还没有公开,于是就自己回来分析了一下. 0x00官方补丁(DB.class ...
- Leetcode 编程训练(转载)
Leetcode这个网站上的题都是一些经典的公司用来面试应聘者的面试题,很多人通过刷这些题来应聘一些喜欢面试算法的公司,比如:Google.微软.Facebook.Amazon之类的这些公司,基本上是 ...
- MQTT---HiveMQ源代码具体解释(十四)Persistence-LocalPersistence
源博客地址:http://blog.csdn.net/pipinet123 MQTT交流群:221405150 简单介绍 HiveMQ的Persistence提供配置包含File和Memory,以解决 ...
- 协程(Coroutine)并不是真正的多线程(转)
自:http://www.zhihu.com/question/23895384 说到Coroutine,我们必须提到两个更远的东西.在操作系统(os)级别,有进程(process)和线程(threa ...
- linux 挂载相关
mount命令的用法,以及技巧光盘镜像文件.移动硬盘.共享文件夹及U盘的方法. 一,挂接命令(mount) 挂接(mount)命令的使用方法. 命令格式: mount [-t vfstype] [- ...
- SQLAlchemy使用笔记--SQLAlchemy ORM(三)
參考: http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#eager-loading 预先载入 前面的代码,由于是lazy load.当我 ...
- Linux下MySQL定时按日期备份数据
一.使用mysql内置命令 mysqldump Usage: mysqldump [OPTIONS] database [tables] mysqldump [OPTIONS] --databases ...
- dede二级导航与二级栏目 ----内容介绍二级导航
{dede:channelartlist typeid='top'}//如果只需要拿一列,则需要使用row='1'这个属性否则会根据子频道的数目循环输出 <a href="{dede: ...