使用Delphi和TINetHttp,为什么我得到一个TINetHttp重定向异常,而不是另一个?

问题描述 投票:1回答:1

请谁能解释一下在下面的情况下发生了什么?是一个ISP重定向了一个URL,但另一个却没有重定向,还是发生了什么不同的事情?

我使用Delphi的TINetHttp(WinInet的一个封装器)登录到ISP上的cpanel并恢复会话代码。我利用TINetHttp的回调方法来获取重定向的URL,并从中提取会话代码。在一个ISP上,代码可以正常工作,但在另一个ISP上,回调给出的异常是 Error 12168 - The HTTP redirect request must be confirmed by the user 并将glboal var NewURL设置为空字符串。

假设登录的URL是 https://MyServer.net:2083/login/?user=username&pass=password 和INetHttp flNoAutoRedirect标志设置为FALSE,因此允许重定向。

var
NewURL : string;
url:= 'https://MyServer.net:2083/login/?user=username&pass=password'
RunWebPageCode(url, true);  //navigate to the logon page, INetHttp callback sets NewURL to the redirected url
SessionID := ExtractBetween(NewURL , '/cpsess', '/frontend');  //get the session code from the redirected url

这里调用INetHttp回调,并将全局变量NewURL设置为重定向的URL(类似于https://MyServer.net:2083/cpsess1111633888/frontend/x3/index.html?login=1&post_login=9962390421682),我从其中提取了来自于 /cpsess/frontend.

在不同的ISP上,使用几乎相同的(正确的)url,只是域名不同,INetHttp1 flNoAutoRedirect标志仍然设置为FALSE,INetHttp回调产生异常12168,NewURL被设置为空字符串。

然而,在这两个ISP中,如果我将flNoAutoRedirect标志设置为TRUE,这样INetHttp回调就不会被调用,我可以从我登陆的空白页面的html中提取会话ID,它将看起来像这样

<html><head><META HTTP-EQUIV="refresh"CONTENT="2;URL=/cpsess1796422993/frontend/paper_lantern/index.html login=1&amp;post_login=99510958918744"></head><body></body></html>

所以下面的代码适用于两个ISP(如果flNoAutoRedirect标志设置为TRUE)。

url:= 'https://MyServer.net:2083/login/?user=username&pass=password'
RunWebPageCode(url, true);  //navigate to the logon page
page := GetWebPageText(url, true);    /get the html of the landing page
SessionID := ExtractBetween(page, '/cpsess', '/frontend'); 

下面是各种函数的完整代码,以备参考。

var
NewURL : string;

procedure Tjhm.RunWebPageCode(TheURL: string; secure: Boolean);
begin
 try
    try
    if secure then
       INetHttp1.Flags := INetHttp1.Flags + [flSecure]
    else
       INetHttp1.Flags := INetHttp1.Flags - [flSecure];
    INetHttp1.Verb := vePost;
    INetHttp1.Url := TheURL ;
    INetHttp1.Open;
    INetHttp1.OpenRequest;
    INetHttp1.SendRequest;
    except
     on E : Exception do
     begin
     showmessage ('error running web page code  +slinebreak
                +  'Exception class name = '+E.ClassName+ slinebreak
                +  'Exception message = '+E.Message);
      end  //on E
     end;
 finally
    INetHttp1.Close;
 end;
 end;

procedure Tjhm.INetHttp1Callback(Sender: TObject; Status: Integer;   Information: Pointer; InformationLength: Integer);
const
  INTERNET_STATUS_REDIRECT = 110; //a constant in WinInet but redefined here for clarity
begin
if Status = INTERNET_STATUS_REDIRECT then  //we have been redirected
    begin
    newURL := PAnsiChar(Information); // put new url into global var, typecast as 'Information' is a pointer to a non unicode char string
    end;
end;

function Tjhm.ExtractBetween(const Value, A, B: string): string;
{utility to get the text between two delimiters}
var
  aPos, bPos: Integer;
begin
  result := '';
  aPos := Pos(A, Value);
  if aPos > 0 then begin
    aPos := aPos + Length(A);
    bPos := PosEx(B, Value, aPos);
    if bPos > 0 then begin
      result := Copy(Value, aPos, bPos - aPos);
    end;
  end;
end;
delphi redirect wininet
1个回答
1
投票

当一个POST请求返回307状态码时,WinInet不会进行自动重定向,而是返回错误12168。

所以我猜测你的第一个ISP返回的是旧的302代码,而另一个返回的是307。

请看 此处 获取完整的HTTP重定向代码列表。

© www.soinside.com 2019 - 2024. All rights reserved.