我在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
似乎没有通过参数。
我显然做错了,所以请有人指出我的白痴。
更新
正如下面的Arioch指出,我应该检查浏览器实际上是在发送数据 - 所以使用Chrome开发者工具我检查了标题,其结果是:
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
因此浏览器肯定会发送表单数据。
答案 0 :(得分:1)
原始编码表单数据存储在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。