奇怪的indy重定向帖子

时间:2017-08-31 20:31:35

标签: delphi post delphi-2010 indy

我正在尝试使用Indy发送帖子请求,但我遇到了一些问题。 在表格中我有TIdHTTP,TIdSSLIOHandlerSocketOpenSSL和带有这些属性的TIdCookieManager:

TIdHTTP:

IdHTTP1.IOHandler := FSSLIO;
IdHTTP1.AllowCookies := True;
IdHTTP1.HandleRedirects := True;
IdHTTP1.ProxyParams.BasicAuthentication := False;
IdHTTP1.ProxyParams.ProxyPort := 0;
IdHTTP1.Request.ContentLength := -1;
IdHTTP1.Request.Accept := 'text/html, */*';
IdHTTP1.Request.BasicAuthentication := False;
IdHTTP1.Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
IdHTTP1.HTTPOptions := [hoKeepOrigProtocol, hoForceEncodeParams];
IdHTTP1.OnRedirect := IdHTTP1Redirect;
IdHTTP1.CookieManager := IdCookieManager1;        

TIdSSLIOHandlerSocketOpenSSL:默认值

TIdCookieManager:默认值

OnRedirect程序:

Handled := True;

在按钮中提供以下请求:

Params := TStringStream.Create('asdf=asdf',TEncoding.UTF8);    
edtmemo1.Text := IdHTTP1.Post('https://www.detran.mg.gov.br/habilitacao/1-habilitacao-quero-ser-condutor/consultar-resultado-exame-legislacao/-/busca_resultado_exames/', Params);
Params.Free;

但是响应代码301返回错误,但是奇怪的部分是该位置与我尝试发送的URL相同,因此它进入无限循环。

响应

HTTP/1.1 301 Moved Permanently
Date: Thu, 31 Aug 2017 20:23:32 GMT
Server: Apache
X-Powered-By: PHP/5.3.5
P3P: CP="A politica de privacidade deve estar disponivel no site ou pode ser solicitada via fale conosco."
Set-Cookie: SECCCAKEPHP=e19ttp30m5380ih41qal0gipg2; expires=Sat, 09-Sep-2017 04:23:32 GMT; path=/
Location: https://www.detran.mg.gov.br/habilitacao/1-habilitacao-quero-ser-condutor/consultar-resultado-exame-legislacao/-/busca_resultado_exames/
Cache-Control: max-age=604800
Expires: Thu, 07 Sep 2017 20:23:32 GMT
Content-Length: 0
Content-Type: text/html; charset=utf-8

卷曲测试:

curl -vv -X POST -F 'asdf=asdf' https://www.detran.mg.gov.br/habilitacao/1-habilitacao-quero-ser-condutor/consultar-resultado-exame-legislacao/-/busca_resultado_exames/

我使用curl尝试了相同的请求,并使用响应代码200。 知道会发生什么事吗?

1 个答案:

答案 0 :(得分:0)

如果您阅读curl documentation,您会看到-F选项以multipart/form-data格式发布数据:

  

-F, - form

     

(HTTP)这使curl模拟用户按下提交按钮的填写表单。 这会导致curl使用根据RFC 2388 的Content-Type multipart / form-data来POST数据。这样可以上传二进制文件等。

但是,您的TIdHTTP代码会发布application/x-www-form-urlencoded格式的数据。更重要的是,您没有将TIdHTTP.Request.ContentType属性设置为'application/x-www-form-urlencoded'以匹配数据。如果您发布TStream,则必须相应地设置ContentType

TIdHTTP更喜欢使用application/x-www-form-urlencoded派生的对象(例如TStrings)而不是TStringList发布TStream数据,因此可以确保数据被正确编码和格式化,例如:

var
  Params: TStringList;
begin
  ...
  Params := TStringList.Create;
  try
    Params.Add('asdf=asdf'); // <-- DO NOT url-encode the values here!
    // the TStrings version of Post() will set the Request.ContentType
    // to 'application/x-www-form-urlencoded' by default...
    edtmemo1.Text := IdHTTP1.Post('https://www.detran.mg.gov.br/habilitacao/1-habilitacao-quero-ser-condutor/consultar-resultado-exame-legislacao/-/busca_resultado_exames/', Params);
  finally
    Params.Free;
  end;
  ...
end;

TIdHTTP更喜欢使用multipart/form-data对象发布TIdMultipartFormDataStream数据(除非您将另一个包含预先格式化的MIME数据的TStream传递给它)。< / p>

因此,要匹配curl命令发送的内容,请尝试以下方法:

uses
  ..., IdMultipartFormData;

var
  Params: TIdMultipartFormDataStream;
begin
  ...
  Params := TIdMultipartFormDataStream.Create;
  try
    Params.AddFormField('asdf', 'asdf', 'utf-8');
    // the TIdMultipartFormDataStream version of Post() will set the
    // Request.ContentType to 'multipart/form-data' with a suitable
    // MIME 'boundary' attribute for you...
    edtmemo1.Text := IdHTTP1.Post('https://www.detran.mg.gov.br/habilitacao/1-habilitacao-quero-ser-condutor/consultar-resultado-exame-legislacao/-/busca_resultado_exames/', Params);
  finally
    Params.Free;
  end;
  ...
end;