【问题标题】:IdHTTP.get returning HTTP1.1/ 403 ForbiddenIdHTTP.get 返回 HTTP1.1/ 403 Forbidden
【发布时间】:2012-01-22 16:48:15
【问题描述】:

我正在尝试使用 DelphiXE 编译程序和 IdHTTP 组件访问我网站上的 update.txt 文件。

我使用的代码如下:

procedure TFormAbout.SpeedButtonUpdateClick(Sender: TObject);

function CheckUpdates: String;
var lIdHttp: TIdHTTP;
begin
  lIdHttp := TIdHTTP.Create(nil);
  result := lIdHttp.Get('http://www.test.com/test_down_load/update.txt');
end;

var
sWebVersion: String;
sVersionList: TStringList;

begin
try
  sWebVersion := Checkupdates;
except
  on E: Exception do
  begin 
    ShowMEssage(E.ErrorMessage);
    MessageDlg('An Error occured checking for an update.',mtError,[mbOK],0);
  end;
end;
if sWebVersion <> '' then
  begin
    sVersionList.CommaText := sWebVersion;
    ShowMessage('Version: ' + sVersionList[0] + ' - ' + 'Date: ' + sVersionList[1]);
  end;
end;

但这会导致错误:HTTP1.1/ 403 Forbidden

IdHTTP 组件已设置有以下属性。

HandleRedirects := true;
HTTPOptions [hoForceEncodeParams];
ProtocolVersion := pv1_1;
Request.UserAgent := Mozilla/5.0 (compatible; Test)

如果我在 IE 浏览器中输入 URL,它会返回没有错误的文件,但是从我的程序访问时,我会收到错误消息。 任何指针将不胜感激。 .htaccess 对于该站点是正确的。 该文件的权限在网站上是正确的:0644。

我是否必须为 IdHTTP 组件设置任何其他属性。我在 about 表单上只有这个组件。我还需要什么吗?

updateinfo.txt 文件只包含引号中的文本: "18.3.5,2011/12/17"

我在这里简单地使用了“测试”来代替我的实际程序名称和 URL。

问候 阿德里安

【问题讨论】:

    标签: delphi indy10 idhttp


    【解决方案1】:

    我在使用 Indy 的 Get() 函数时遇到了完全相同的问题。

    您很可能收到此错误,因为您没有设置 UserAgent 属性,并且网站知道您没有访问该文件,因为浏览器正在大惊小怪。

    function CheckUpdates: String;
    var lIdHttp: TIdHTTP;
    begin
      lIdHttp := TIdHTTP.Create(nil);
      //avoid getting '403 Forbidden' by setting UserAgent
      lIdHttp.Request.UserAgent :=
          'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20100101 Firefox/12.0';
      result := lIdHttp.Get('http://www.test.com/test_down_load/update.txt');
    end;
    

    类似的问题,但在此处记录了正确答案: https://stackoverflow.com/questions/10870730/why-do-i-get-403-forbidden-when-i-connect-to-whatismyip-com

    【讨论】:

      【解决方案2】:

      403 表示您无权访问请求的 URL。服务器可能要求您提供用户名/密码,尤其是因为您使用的是 .htaccess 文件。为此,请使用 Request.UserNameRequest.Password 属性。至于为什么浏览器不要求输入用户名/密码,我的猜测是浏览器将它们从较早的访问中缓存起来。

      顺便说一句,您的SpeedButtonUpdateClick() 有内存泄漏。您正在创建一个新的 TIdHTTP 对象,但您没有释放它。

      【讨论】:

      • 您好 Remy,我没有为该站点设置用户名或密码。我可以从另一台不属于我的 PC 上的网络浏览器访问该 URL。感谢内存泄漏..只是示例代码,但你是对的,它需要被释放。
      • 然后使用数据包嗅探器,例如 Wireshark,查看来自您的浏览器和 TIdHTTP 的 HTTP 请求是什么样的,然后比较它们的差异。顺便说一句,也许您的服务器不喜欢您正在使用的 Request.UserAgent 的值。一些服务器对 UserAgent 敏感。
      • 我也很担心 Request.UserAgent,尝试了很多变体,都没有成功。
      • 你好雷米,其实问题出在我身上。正如您在代码中看到的那样,我正在创建 TIdHTTP,但没有更改其 Request.UserAgent,而是我在表单上放置的 IdHttp1 组件,因此正在发送默认的 Mozilla/3.0(兼容;Indy 库),而不是我认为我一直在发送的东西。所以我对 component.properties 和测试所做的所有更改都没有通过。在创建 lIdHttp 之后添加这行代码: lIdHttp.request.useragent := 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; MAAU)';谢谢阿德里安
      • 仅供参考,几分钟前我签入了一个更新,其中默认 TIdHTTP.Request.UserAgent 现在可以自定义。 IdHTTPHeaderInfo.pas 单元中有一个新的 GIdDefaultUserAgent 全局变量。您现在可以在程序启动时设置一次GIdDefaultUserAgent 并且每个TIdHTTP 请求都将使用它(您仍然可以使用TIdHTTP.Request.UserAgent 覆盖UserAgent on如果需要,基于每个请求)。
      【解决方案3】:

      在我将所有答案放在一起之前,给出的答案对我不起作用。

      //add Request.Username and supply the correct mysql username
      tidHttpObject.Request.Username := 'username';
      
      //do the same for the password
      tidHttpObject.Request.Password := 'password';
      
      //then add a UserAgent property with the string below
      tidHttpObject.Request.UserAgent :=  'Mozilla/5.0 (Windows NT 6.1; WOW64;
      rv:12.0) Gecko/20100101 Firefox/12.0';
      
      //finally call the get() url method of the tidHttp object
      Result :=  tidHttpObject.Get(url);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-08-26
        • 1970-01-01
        • 1970-01-01
        • 2014-06-15
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        相关资源
        最近更新 更多