在 Delphi 中使用 TIdHTTP 来模拟 curl 命令
use TIdHTTP in Delphi to simulate curl command
我正在尝试使用 IdHTTP 来等效于以下 curl 操作:
curl -X POST -F "message=@C:\Users\santon\Desktop\ESM_download\token.txt" "https://esm-db.eu/esmws/eventdata/1/query?eventid=IT-1997-0004&station=CLF&format=ascii" -o RecordFileName.zip
curl 命令用于从服务器下载文件,然后保存在硬盘上 DownloadedFileName.zip。需要通过硬盘驱动器上名为 token.txt 的令牌文件进行授权。令牌文件的路径被指定为 curl 的参数。
我能做的最好的是以下代码:
procedure TMainForm.HTTPGetFile;
var
IdHTTP: TIdHTTP;
Params: TIdMultipartFormDataStream;
LHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
try
Params := TIdMultipartFormDataStream.Create;
Params.AddFormField('message', '@"C:\Users\santon\Desktop\ESM_download\token.txt"');
IdHTTP := TIdHTTP.Create(nil);
LHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(self);
LHandler.SSLOptions.Method := sslvTLSv1;
try
IdHTTP.IOHandler := LHandler;
IdHTTP.Post('https://esm-db.eu/esmws/eventdata/1/query?eventid=IT-1997-0004&station=CLF&format=ascii',Params);
finally
IdHTTP.Free;
LHandler.Free;
Params.Free;
end;
except
on E: Exception do
ShowMessage('Error: '+E.ToString);
end;
end;
但我不断收到 HTTP/1.1 403 禁止错误。
对我做错了什么有什么想法吗?
提前致谢
您没有将令牌文件正确加载到 TIdMultiPartFormDataStream
。
根据 curl 文档:
https://curl.se/docs/manpage.html#-F
-F, --form <name=content>
(HTTP SMTP IMAP) For HTTP protocol family, this lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST data using the Content-Type multipart/form-data according to RFC 2388.
...
This enables uploading of binary files etc. To force the 'content' part to be a file, prefix the file name with an @ sign. To just get the content part from a file, prefix the file name with the symbol <. The difference between @ and < is then that @ makes a file get attached in the post as a file upload, while the < makes a text field and just get the contents for that text field from a file.
...
Example: send an image to an HTTP server, where 'profile' is the name of the form-field to which the file portrait.jpg will be the input:
curl -F profile=@portrait.jpg https://example.com/upload.cgi
...
在您的代码中,您正在创建一个文本字段,其内容是文件名本身。您没有创建 文件上传 字段,其内容是文件中的数据。
试试这个:
procedure TMainForm.HTTPGetFile;
var
IdHTTP: TIdHTTP;
Params: TIdMultipartFormDataStream;
LHandler: TIdSSLIOHandlerSocketOpenSSL;
LOutFile: TFileStream;
begin
try
Params := TIdMultipartFormDataStream.Create;
try
Params.AddFile('message', 'C:\Users\santon\Desktop\ESM_download\token.txt');
IdHTTP := TIdHTTP.Create(nil);
try
LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
LHandler.SSLOptions.Method := sslvTLSv1;
IdHTTP.IOHandler := LHandler;
LOutFile := TFileStream.Create('<path>\RecordFileName.zip', fmCreate);
try
IdHTTP.Post('https://esm-db.eu/esmws/eventdata/1/query?eventid=IT-1997-0004&station=CLF&format=ascii', Params, LOutFile);
finally
LOutFile.Free;
end;
finally
IdHTTP.Free;
end;
finally
Params.Free;
end;
except
on E: Exception do
ShowMessage('Error: ' + E.ToString);
end;
end;
我正在尝试使用 IdHTTP 来等效于以下 curl 操作:
curl -X POST -F "message=@C:\Users\santon\Desktop\ESM_download\token.txt" "https://esm-db.eu/esmws/eventdata/1/query?eventid=IT-1997-0004&station=CLF&format=ascii" -o RecordFileName.zip
curl 命令用于从服务器下载文件,然后保存在硬盘上 DownloadedFileName.zip。需要通过硬盘驱动器上名为 token.txt 的令牌文件进行授权。令牌文件的路径被指定为 curl 的参数。 我能做的最好的是以下代码:
procedure TMainForm.HTTPGetFile;
var
IdHTTP: TIdHTTP;
Params: TIdMultipartFormDataStream;
LHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
try
Params := TIdMultipartFormDataStream.Create;
Params.AddFormField('message', '@"C:\Users\santon\Desktop\ESM_download\token.txt"');
IdHTTP := TIdHTTP.Create(nil);
LHandler:= TIdSSLIOHandlerSocketOpenSSL.Create(self);
LHandler.SSLOptions.Method := sslvTLSv1;
try
IdHTTP.IOHandler := LHandler;
IdHTTP.Post('https://esm-db.eu/esmws/eventdata/1/query?eventid=IT-1997-0004&station=CLF&format=ascii',Params);
finally
IdHTTP.Free;
LHandler.Free;
Params.Free;
end;
except
on E: Exception do
ShowMessage('Error: '+E.ToString);
end;
end;
但我不断收到 HTTP/1.1 403 禁止错误。 对我做错了什么有什么想法吗?
提前致谢
您没有将令牌文件正确加载到 TIdMultiPartFormDataStream
。
根据 curl 文档:
https://curl.se/docs/manpage.html#-F
-F, --form <name=content>
(HTTP SMTP IMAP) For HTTP protocol family, this lets curl emulate a filled-in form in which a user has pressed the submit button. This causes curl to POST data using the Content-Type multipart/form-data according to RFC 2388.
...
This enables uploading of binary files etc. To force the 'content' part to be a file, prefix the file name with an @ sign. To just get the content part from a file, prefix the file name with the symbol <. The difference between @ and < is then that @ makes a file get attached in the post as a file upload, while the < makes a text field and just get the contents for that text field from a file.
...
Example: send an image to an HTTP server, where 'profile' is the name of the form-field to which the file portrait.jpg will be the input:
curl -F profile=@portrait.jpg https://example.com/upload.cgi
...
在您的代码中,您正在创建一个文本字段,其内容是文件名本身。您没有创建 文件上传 字段,其内容是文件中的数据。
试试这个:
procedure TMainForm.HTTPGetFile;
var
IdHTTP: TIdHTTP;
Params: TIdMultipartFormDataStream;
LHandler: TIdSSLIOHandlerSocketOpenSSL;
LOutFile: TFileStream;
begin
try
Params := TIdMultipartFormDataStream.Create;
try
Params.AddFile('message', 'C:\Users\santon\Desktop\ESM_download\token.txt');
IdHTTP := TIdHTTP.Create(nil);
try
LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
LHandler.SSLOptions.Method := sslvTLSv1;
IdHTTP.IOHandler := LHandler;
LOutFile := TFileStream.Create('<path>\RecordFileName.zip', fmCreate);
try
IdHTTP.Post('https://esm-db.eu/esmws/eventdata/1/query?eventid=IT-1997-0004&station=CLF&format=ascii', Params, LOutFile);
finally
LOutFile.Free;
end;
finally
IdHTTP.Free;
end;
finally
Params.Free;
end;
except
on E: Exception do
ShowMessage('Error: ' + E.ToString);
end;
end;