简体   繁体   English

Delphi从Web获得具有表单授权的文件

[英]Delphi download file from Web with Form authorization

I need download file from Web with authorization. 我需要授权从Web下载文件。 I use Delphi and Indy components. 我使用Delphi和Indy组件。 When the method Get performs the download, I get error "HTTP/1.0 404 Not Found". 当Get方法执行下载时,出现错误“ HTTP / 1.0 404 Not Found”。 That seems to say that the authorization is failed, but file Response.html contains Web page, similar to the one that appears after login … 这似乎表明授权失败,但是文件Response.html包含网页,类似于登录后出现的网页……

PS Prams for authorization form I took using Firefox Web development tools. 我使用Firefox Web开发工具获得的PS Prams授权表。

function TForm1.Login: string;
var
    Request: TStringList;
begin
    Result := '';
    try
        Request := TStringList.Create;
        try
            Request.Add('backurl=%2Fnewupgrade%2Findex.php');
            Request.Add('AUTH_FORM=Y');
            Request.Add('TYPE=AUTH');
            Request.Add('USER_LOGIN=xxxx');
            Request.Add('USER_PASSWORD=XXXX');
            IdHTTP1.AllowCookies := True;
            IdHTTP1.HandleRedirects := True;
            IdHTTP1.Request.ContentType := 'application/x-www-form-urlencoded';
            IdHTTP1.Request.Connection := 'keep-alive';
            Result := IdHTTP1.Post('http://www.uniko.ru/newupgrade/index.php?login=yes', Request);
        finally
            Request.Free;
        end;
    except
        on E: Exception do ShowMessage(E.Message);
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
    Response: string;
    fs: TStreamWriter;
    MS: TMemoryStream;
begin
    Response := Login;
    fs := TStreamWriter.Create('C:\Response.html');
    fs.Write(Response);
    fs.Free;

    // Download file
    MS := TMemoryStream.Create;
    try
        IdHTTP1.Request.ContentType := 'application/force-download; name="Setup.EXE"';
        IdHTTP1.Get('http://www.uniko.ru/newupgrade/izyat/Setup.EXE', MS);
        MS.SaveToFile('C:\Setup.tmp');
    finally
        MS.Free;
    end
end;

HTTP response code 404 means the requested URL was not found. HTTP响应代码404表示找不到请求的URL。 You are thinking of 401, which is the server's request for authentication. 您正在考虑401,这是服务器的身份验证请求。 TIdHTTP handles 401 internally, but depending on what kind of authentication it is asking for (Basic, NTLM, SSPI, etc), you may need to add various IdAuthentication... units to your uses clause to enable Indy's support for them. TIdHTTP内部处理401,但是根据其要求的身份验证类型(基本,NTLM,SSPI等),您可能需要在uses子句中添加各种IdAuthentication...单元,以启用Indy对它们的支持。

The only way your code would write to Response.html is if the Post() reported HTTP response code 200 instead of 401, but is sent back the login page. 您的代码写入Response.html的唯一方法是Post()报告HTTP响应代码200而不是401,但是将其发送回登录页面。 The site is using webform authentication, not HTTP authentication. 该网站使用的是Webform身份验证,而不是HTTP身份验证。 When posting a TStrings for webform authentication, do not url-encode the contents. 发布用于Webform身份验证的TStrings ,请勿对内容进行url编码。 Post() handles that internally for you. Post()在内部为您处理。 Specifically, this line: 具体来说,此行:

Request.Add('backurl=%2Fnewupgrade%2Findex.php');

Should be this instead: 应该是这样的:

Request.Add('backurl=/newupgrade/index.php');

That may be causing the webform to fail, and might account for the 404. Look at the HTML being sent back, it might contain an error message in it. 这可能会导致Web表单失败,并可能导致404错误。看看发送回的HTML,其中可能包含错误消息。

I find solution!!! 我找到解决办法!!!

I read this article: http://www.programmersclub.ru/%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D0%BD%D0%B0-mail-ru-%D1%81-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E-indy/ 我读了这篇文章: http : //www.programmersclub.ru/%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1% 86%D0%B8%D1%8F-%D0%BD%D0%B0-邮件rU-亚%D1%81-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1 %8C%D1%8E-印/

and decide add Cooke parameter to HTTP1.Response.RawHeaders: 并确定将Cooke参数添加到HTTP1.Response.RawHeaders:

procedure TForm1.Button1Click(Sender: TObject);
var
  header, cookie: string;
  MS: TMemoryStream;
  p, p2: Integer;
begin
  Login;

  cookie := '';
  header := IdHTTP1.Response.RawHeaders.Text;
  while true  do begin
    p := pos('Cookie:', header);
    if p=0 then break;
    p := p+length('Cookie:')+1;
    p2 := pos(#$D#$A, copy(header, p, length(header)));
    if p2=0 then p2 := length(header);
    cookie := cookie + copy(header, p, p2-1)+';';
    header := copy(header, p+p2+1, length(header))
  end;

  if cookie<>'' then begin
    cookie := StringReplace(cookie, 'path=/;', '', [rfReplaceAll]);
    cookie := copy(cookie, 1, length(cookie)-1);
    IdHTTP1.Request.CustomHeaders.Add('Cookie: ' + cookie);
  end;

  // Download file
  MS := TMemoryStream.Create;
  try
    IdHTTP1.Request.ContentType := 'application/force-download; name="Setup.EXE"';
    IdHTTP1.Get('http://www.uniko.ru/newupgrade/izyat/Setup.EXE', MS);
    MS.SaveToFile('C:\Setup.tmp');
  finally
    MS.Free;
  end
end;

And its work! 和它的工作!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM