Delphi7 Indy HTTPServer 没有获取表单参数
Delphi7 Indy HTTPServer not getting form parameters
我在 Windows 应用程序中有一个 Indy 10 IdHTTPServer,它提供一个带有两个文本框和一个提交按钮的虚拟 HTML 表单。当在浏览器中按下按钮时,我没有看到任何返回到服务器的表单参数。
请注意,这是一些概念验证代码,将用于使 windows 服务响应 Web 表单中的按钮按下。
HTML形式是这样的:
<form action="http://<addressofsite>/" method="post">
First name:<br>
<input type="text" name="firstname" value="Mickey"><br>
Last name:<br>
<input type="text" name="lastname" value="Mouse"><br><br>
<input type="submit" value="Submit">
</form>
在 Delphi 代码中我有这个:
procedure TForm1.HTTPServer1CommandGet(AThread: TIdPeerThread;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
...
if ARequestInfo.Command = 'POST' then
begin
{******* POSTS ***************}
Memo1.Text := ARequestInfo.RawHTTPCommand;
end;
end;
我尝试了 ARequestInfo 结构的各个部分,但无论我尝试什么,在浏览器中按下按钮时我看到的是:
POST / HTTP 1.1
似乎没有传递任何参数。
我显然做错了什么,所以请有人指出我的白痴。
更新:
正如下面的 The Arioch 所指出的,我应该检查浏览器是否确实在发送数据 - 因此我使用 Chrome 开发人员工具检查了 headers,其结果是:
Response Headers
Connection:close
Content-Type:text/html
Server:Indy/10.0.52
Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image /webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, br
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Authorization:Basic YWRtaW46cGFzcw==
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:31
Content-Type:application/x-www-form-urlencoded
Host:127.0.0.1:8091
Origin:http://127.0.0.1:8091
Referer:http://127.0.0.1:8091/main
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Form Data
firstname:Mickey
lastname:Mouse
所以浏览器肯定是在发送表单数据。
原始编码表单数据存储在ARequestInfo.FormParams
和ARequestInfo.UnparsedParams
属性中。
如果 TIdHTTPServer.ParseParams
为真(默认情况下为真),则 解码后的 表单数据存储在 ARequestInfo.Params
属性 中,例如:
procedure TForm1.HTTPServer1CommandGet(AThread: TIdPeerThread;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
FirstName, LastName: string;
begin
...
if (ARequestInfo.CommandType = hcPOST) and
IsHeaderMediaType(ARequestInfo.ContentType, 'application/x-www-form-urlencoded') then
begin
FirstName := ARequestInfo.Params.Values['firstname'];
LastName := ARequestInfo.Params.Values['lastname'];
...
end;
end;
请注意,TIdHTTPServer
是一个多线程组件。包括 OnCommandGet
在内的各种事件在工作线程的上下文中触发。因此,如果您需要触摸 UI 控件,例如您的 TMemo
,您 必须 与主 UI 线程同步,例如:
procedure TForm1.HTTPServer1CommandGet(AThread: TIdPeerThread;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
...
if (ARequestInfo.CommandType = hcPOST) and
HeaderIsMediaType(ARequestInfo.ContentType, 'application/x-www-form-urlencoded') then
begin
TThread.Synchronize(nil,
procedure
begin
Memo1.Text := ARequestInfo.Params.Text;
end
);
...
end;
end;
此外,10.0.52 是 Indy 的过时版本。当前版本(在撰写本文时)是 10.6.2.5384。
我在 Windows 应用程序中有一个 Indy 10 IdHTTPServer,它提供一个带有两个文本框和一个提交按钮的虚拟 HTML 表单。当在浏览器中按下按钮时,我没有看到任何返回到服务器的表单参数。 请注意,这是一些概念验证代码,将用于使 windows 服务响应 Web 表单中的按钮按下。
HTML形式是这样的:
<form action="http://<addressofsite>/" method="post">
First name:<br>
<input type="text" name="firstname" value="Mickey"><br>
Last name:<br>
<input type="text" name="lastname" value="Mouse"><br><br>
<input type="submit" value="Submit">
</form>
在 Delphi 代码中我有这个:
procedure TForm1.HTTPServer1CommandGet(AThread: TIdPeerThread;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
...
if ARequestInfo.Command = 'POST' then
begin
{******* POSTS ***************}
Memo1.Text := ARequestInfo.RawHTTPCommand;
end;
end;
我尝试了 ARequestInfo 结构的各个部分,但无论我尝试什么,在浏览器中按下按钮时我看到的是:
POST / HTTP 1.1
似乎没有传递任何参数。
我显然做错了什么,所以请有人指出我的白痴。
更新:
正如下面的 The Arioch 所指出的,我应该检查浏览器是否确实在发送数据 - 因此我使用 Chrome 开发人员工具检查了 headers,其结果是:
Response Headers
Connection:close
Content-Type:text/html
Server:Indy/10.0.52
Request Headers
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image /webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, br
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Authorization:Basic YWRtaW46cGFzcw==
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:31
Content-Type:application/x-www-form-urlencoded
Host:127.0.0.1:8091
Origin:http://127.0.0.1:8091
Referer:http://127.0.0.1:8091/main
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Form Data
firstname:Mickey
lastname:Mouse
所以浏览器肯定是在发送表单数据。
原始编码表单数据存储在ARequestInfo.FormParams
和ARequestInfo.UnparsedParams
属性中。
如果 TIdHTTPServer.ParseParams
为真(默认情况下为真),则 解码后的 表单数据存储在 ARequestInfo.Params
属性 中,例如:
procedure TForm1.HTTPServer1CommandGet(AThread: TIdPeerThread;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
FirstName, LastName: string;
begin
...
if (ARequestInfo.CommandType = hcPOST) and
IsHeaderMediaType(ARequestInfo.ContentType, 'application/x-www-form-urlencoded') then
begin
FirstName := ARequestInfo.Params.Values['firstname'];
LastName := ARequestInfo.Params.Values['lastname'];
...
end;
end;
请注意,TIdHTTPServer
是一个多线程组件。包括 OnCommandGet
在内的各种事件在工作线程的上下文中触发。因此,如果您需要触摸 UI 控件,例如您的 TMemo
,您 必须 与主 UI 线程同步,例如:
procedure TForm1.HTTPServer1CommandGet(AThread: TIdPeerThread;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
...
if (ARequestInfo.CommandType = hcPOST) and
HeaderIsMediaType(ARequestInfo.ContentType, 'application/x-www-form-urlencoded') then
begin
TThread.Synchronize(nil,
procedure
begin
Memo1.Text := ARequestInfo.Params.Text;
end
);
...
end;
end;
此外,10.0.52 是 Indy 的过时版本。当前版本(在撰写本文时)是 10.6.2.5384。