使用Delphi XE5 + Indy 10。
我正在发送带有登录名和密码的 POST 来登录。站点响应重定向 (302) 到目标页面。在浏览器中,重定向由 GET 处理,一切正常,但 Indy 继续使用 POST。
我通过在 OnRedirect 处理程序中使用以下代码解决了这个问题:
procedure TForm1.MyRedirect(Sender: TObject;
var dest: string;
var NumRedirect: Integer;
var Handled: Boolean;
var VMethod: string);
var
TempHttp: TIdHttp;
begin
TempHttp := (Sender as TIdHTTP);
if (TempHttp.ResponseCode = 302) then
VMethod := 'GET';
Handled := true;
end;
请求方法随后更改为 GET,但 Indy 仍然使用 GET 发送 POST 请求参数。所以我得到 413 Request Entity Too Large 响应。
如何让 Indy 在重定向后不使用 GET 发送参数? OnRedirect 内部的解决方案将是理想的。
谢谢!
最佳答案
处理 HTTP 302
回复代码的客户端行为是不明确的,并且经常被各种客户端错误地处理。这在各种 RFC 中都有详细记录,包括 2068 和 2616。创建 303
回复代码是为了解决歧义,但许多客户端仍然不支持 303
,并且许多客户端仍然不支持 303
。服务器仍然使用 302
,期望客户端的行为就像使用 303
一样。
TIdHTTP
多年来来回跳了很多次,试图找出收到 302
时应该使用什么行为 - 是否应该使用 GET 进行重定向
,还是应该使用 POST
进行重定向? 2012 年,TIdHTTP.HTTPOptions
属性中添加了 hoTreat302Like303
标志,让用户决定要执行的操作。因此,请确保您使用的是最新版本的 Indy。
如果收到 303
,TIdHTTP
将清除其 Request.Source
属性(从而忽略之前的任何 POST
params) 并发送 GET
请求,忽略 OnRedirect
事件处理程序返回的方法(如果已分配)。
如果收到302
:
如果启用了
hoTreat302Like303
,TIdHTTP
将清除其Request.Source
属性(从而忽略之前的任何POST
params) 并发送GET
请求,忽略OnRedirect
事件处理程序返回的方法(如果已分配)。如果
hoTreat302Like303
被禁用(默认情况下),TIdHTTP
将使用OnRedirect
返回的方法发送请求> 如果已分配事件处理程序,否则它将使用与重定向的上一个请求相同的方法发送请求。但无论哪种情况,它都不会清除其Request.Source
属性(因此任何先前的POST
参数都将被重新发送)。因此,如果您更改OnRedirect
处理程序中的方法,则还必须相应地更新Request.Source
属性,例如:procedure TForm1.MyRedirect(Sender: TObject; var dest: string; var NumRedirect: Integer; var Handled: Boolean; var VMethod: string); var TempHttp: TIdHttp; begin TempHttp := (Sender as TIdHTTP); if (TempHttp.ResponseCode = 302) then begin VMethod := 'GET'; TempHttp.Request.Source := nil; // <-- add this end; Handled := true; end;
关于delphi - Indy 在 POST 重定向后使用 GET 发送参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24168465/