使用 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&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。
有人可以解释一下在以下情况下发生了什么吗? 是一个 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&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。