2017-08-31 148 views
1

我想發送一個帖子請求使用Indy但我面臨一些問題。 在一種形式中我有TIdHTTP,一個TIdSSLIOHandlerSocketOpenSSL和TIdCookieManager蒙山這些屬性:奇怪的indy重定向後

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 作品有什麼可以發生任何想法?

+0

服務器重定向到相同的URL,但它也發送一個Cookie,很可能在初始請求丟失。如果服務器想要返回cookie,這是合理的行爲。如果服務器陷入無盡的重定向循環,那是一個不同的問題。嗅探流量以查看curl發送的內容與「TIdHTTP」發送的內容。要嗅探curl的HTTPS流量,可以使用[Fiddler](http://www.telerik.com/fiddler)。要嗅探TIdHTTP的HTTPS流量,可以將'TIdLog ...'組件分配給'TIdHTTP.Intercept'屬性,例如'TIdLogFile'。 'TIdHTTP'發送了那個cookie嗎? –

+2

你傳遞什麼命令行參數來捲曲?你傳遞給'TIdHTTP.Post()'什麼'Params'?請提供[mcve]顯示您實際正在執行的所有事情以重現問題。此外,德爾福2010年8歲,你是否使用同樣舊版本的印地?在撰寫本文時,目前的Indy版本是10.6.2.5434。 –

+0

我編輯了問題,添加了curl請求,並且使用這些參數,curl不處理重定向,但用200代碼進行響應。 我可以在curl中模擬相同的問題的唯一方法是,如果不是https,我使用http。 是的,我知道德爾福2010年是舊的,是的,我使用Indy 10.5.5版本,我們已經嘗試更新,至少Indy,但我們遇到很多問題,很不幸我們沒有足夠的時間或人員來處理它。 – Rigotti

回答

0

如果你讀了curl documentation,你會看到,在multipart/form-data格式-F選項職位數據:

-F,--form

(HTTP)這讓捲曲模擬填充 - 用戶按下提交按鈕的表單。 這會導致根據RFC 2388使用內容類型多部分/表單數據捲曲到POST數據。這樣可以上傳二進制文件等。

但是,您的TIdHTTP代碼發佈的數據是application/x-www-form-urlencoded格式。更重要的是,您並未將TIdHTTP.Request.ContentType屬性設置爲'application/x-www-form-urlencoded'以匹配數據。如果您發佈TStream,則必須相應地設置ContentType

TIdHTTP寧願使用TStrings派生對象被張貼application/x-www-form-urlencoded數據(如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對象進行發佈(除非您將另一個TStream傳遞給其中包含預格式化的MIME數據)。

因此,以符合你的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; 
+0

非常感謝你@remy-lebeau的答案,嘗試了你的建議,但不幸的是沒有奏效。現在它用'Content-Type:multipart/form-data;邊界= -------- 090117161550011'。但相同的結果 – Rigotti

+0

使用當前版本的Indy與您在問題中顯示的確切代碼,我無法重現該問題。沒有做出我在我的回答中提出的任何更改,服務器回覆200包含HTML文檔,而不是回覆301重定向。所以,你需要做我最初的建議:「*嗅探流量,看看curl發送什麼與TIdHTTP發送什麼*」。服務器不喜歡的機器上的TIdHTTP請求顯然存在(或丟失)。任何捲曲發送,'TIdHTTP'可以複製與正確的編碼 –

+0

我試圖使用Fiddler,我認爲這可能是SSL的一些問題,因爲在提琴手嘗試'連接'到服務器,並返回408錯誤的請求。 – Rigotti