设为首页 加入收藏

TOP

使用 TRESTClient 与 TRESTRequest 作为 HTTP Client(二)
2017-10-09 13:58:54 】 浏览:6566
Tags:使用 TRESTClient TRESTRequest 作为 HTTP Client
码读起来比较简洁易懂,所以我就选择 PHP 来做范例了。

在 PHP 里面,透GET 跟 POST 方法传递的参数,会被分存放在 $_GET 跟 $_POST 两个数里面,如果要偷懒,不想区分 GET 或 POST 方法,也可以从 $_REQUEST 取,当中有些安全性考量,最好勤一点,把它区分开来。

 

刚刚的例子来看,我们传了一个名 name,以及一个名 test 的字串,用的是 POST 方法,所以我得用以下两个数来存取两个字串:

?  $_POST['name']  数可以取得 Client 端送出来的 name 

?  $_POST['test']  数可以取得 Client 端送出来的 test

所以在 server 端,我可以这样写,来抓到两个料:

$name = $_POST["name"];

$test = $_POST["test"];

 

这样写会不会出问题呢? 答案是不会!如果使用者不入中文的

 

中文料的编码处

Delphi的开员绝大多数都是英美系的人,我推因此系的文字示与传输没有法完整的测试,但于我以中文的人来,从电脑诞生的那个年代,中文的示在每个操作、每种通讯协定的设计都比英文来的困

以上面的例子来看,如果我直接拿个例子来测试,笔者写的范例程式,传输资,Server 所抓到的文字并不是正确的中文字,如下所示:              

  

可以看得出来,到 server 的候,server 是不到资讯的。是怎么回事呢?笔者属于不认输的好奇宝宝,使出了身解数,于解决了问题

 

Web 程式的一定可以立刻推出来,这绝对是文字编码问题了,然而,是什么地方出问题?可能出问题的点我列出来跟大家分享:

?  HTTP Client 的 charset

?  HTTP Request 里面的文字编码问题

检查的方向也是从两个关点出,第一点的检测很容易,从Object Inspector检查一下 RESTRequest1的定:

AcceptCharset 确定是 UTF-8,没,所以定不是问题

接着,就要从 Client 端出去的料下手了。有者或『你怎么不怀疑Server端程式写了?』问题很好,之所以排除了问题,是因同一个 Server 端的 PHP 程式,我用了 Postman 做对测试,回果是正确的,因此判定是 Client 端程式的问题

接着笔者从 TRESTRequest.AddParameter 的各种多形式来尝试,AddParameter 个方法有以下几种多的形式:

procedure AddParameter(const AName, AValue: string); overload;
procedure AddParameter(const AName: string; AJsonObject: TJSONObject; AFreeJson: boolean = true); overload;
procedure AddParameter(const AName, AValue: string; const AKind: TRESTRequestParameterKind); overload;

三种形式我都测试过,从 AddParameter 的行中 trace 去看各个可能性,由于 TRESTRequest 的参数中,Get 跟 Post 的加入方法是混用的,在程式里面编码又会有点不同。

在 REST.Client.pas 里面,我曾经怀过编码错误,所以也在各个数都察,最后,找到了原因与解法,至于程,就不多了,花了我两天咧。

原因:编码错误

用HTTP传递中文的候,必用UTF-8编码,但一定要得,中文字在作中,都是UCS32编码象在Windows里面如此,在Android里面如此,在iOS跟Mac我不确定,但理方法是一的。

直接以 AddParameter('name', '中文测试'); 把参数加 TRESTRequest 候,REST.Client.pas 的程式是把 '中文测试' 个字串直接抓 Ord 的料来做编码的,然而,个作法,是的!!!!!!!!

在 HTTP 传递 UTF-8 料的候,我传递的是 UTF-8 文字的二料,但直接把 '中文测试' 个字串直接拿来成二位? 当时编码并不是 UTF-8 啊,当然怎么编码送到 server 都是的!!!!

解法:AddParameter之前先做 UTF-8 转换

个解法,笔者第一天就已想到,只是很想像以前改 Indy 程式一,直接改好 REST.Client.pas 之后,回馈给原厂使用,所以花了不少时间找方法,最后发现这个方法不用到 REST.Client.pas,又能正确理,就直接么跟大家分享了,写成 Delphi 程式如下:

var
     nameStr : String;
begin
   ...
   nameStr := TIdURI.ParamsEncode(nameStr, IndyTextEncoding_UTF8);
   self.RESTRequest1.AddParameter('name', nameStr,      
             TRESTRequestParameterKind.pkGETorPOST,     
             [TRESTRequestParameterOption.poDoNotEncode]);
   ... 
end;

在把字串透 AddParameter 加入参数列之前,我先把字串做个 UTF-8 转换,在里用的是 TIdURI 的类别方法 ParamsEncode,个方法只有两个参数,第一个参数是字串内容,第二个参数是要文字编码的种,在里我选择了 UTF8,写法就是上面范例程式的第一行。

接着,在呼叫 AddParameter 的候,我使用了多形式当中的第三种,要求 AddParameter 料的候不要再我的编码,因我已经处理好了。

这么修改过之后,在各个作业系统当中,执行结果都是正确的,上面两个图以 Windows 作业系统为例,现在我们拿 Android 截图来做为例子:


者可以看到右的截里面,server 回料已是正确的中文字了。

最后,我把 PHP 程式也附上来大家参考:

 1 <?php
 2 date_default_timezone_set("Asia/Taipei");
 3 header('Content-Type: charset=utf-8');
 4 
 5 include("public/DBClassPDO.php");
 6 $objDBPDO = new DBClassPDO();
 7 
 8 $cardNum = $_POST["cardNum"];
 9 $floor
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇delphi XE Datasnap SERVER 在win.. 下一篇Delphi提取PDF文本

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目