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

Using Delphi and TINetHttp, why do I get a TINetHttp redirect exception with one url but not another?

有人可以解释一下在以下情况下发生了什么吗? 是一个 ISP 正在重定向 URL 但另一个 ISP 没有重定向,或者发生了什么不同的事情?

我正在使用 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,因此重定向是 allowed.Then 以下将从一个 ISP

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;

当 POST 请求 returns 307 状态代码时,WinInet 不会执行自动重定向,而是 returns 错误 12168。

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

有关 HTTP 重定向代码的完整列表,请参阅 here