将https请求从java转换为delphi

时间:2018-02-23 13:50:30

标签: java delphi idhttp

拥有以下java代码:

    // Set your API key: remember to change this to your live API key in production
    String apiKeyUserName = "your api username";
    String apiKeyPassword = "your api password";

    // Set the query params
    DefaultHttpClient httpclient = new DefaultHttpClient();

    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("fromPostcode", "2000"));
    params.add(new BasicNameValuePair("toPostcode", "3000"));
    params.add(new BasicNameValuePair("networkId", "01"));
    params.add(new BasicNameValuePair("lodgementDate", "2013-08-01"));
    String query = URLEncodedUtils.format(params, "UTF-8");

    String urlPrefix = "api.auspost.com.au";
    String validateURL = "https://" + urlPrefix + "/DeliveryDates.xml?";

    HttpGet httpGet = new HttpGet(validateURL + query);
    httpGet.addHeader("Cookie", "OBBasicAuth=fromDialog");
    httpGet.addHeader(BasicScheme.authenticate(
        new UsernamePasswordCredentials(apiKeyUserName, apiKeyPassword),
        "US-ASCII",false));

HttpResponse response = httpclient.execute(httpGet);

想要将其翻译成Delphi。对于请求,我使用TIdHttp如下:

procedure RequestDeliveryDate;
var
  IdHTTP: TIdHTTP;
  LHandler: TIdSSLIOHandlerSocketOpenSSL;
  lResponse: String;
  requestURL: String;
begin
  IdHTTP := TIdHTTP.Create();
  IdHTTP.Request.BasicAuthentication := True;
  IdHTTP.Request.Username := 'your api username';
  IdHTTP.Request.Password := 'your api password';
  IdHTTP.Request.CharSet := 'utf-8';

  LHandler := TIdSSLIOHandlerSocketOpenSSL.Create();
  IdHTTP.IOHandler := LHandler;

  requestURL := 'https://api.auspost.com.au/DeliveryDates.xml?fromPostcode=2000' +
                                                            '&toPostcode=3000' +
                                                            '&networkId=01' +
                                                            '&lodgementDate=2018-02-23' +
                                                            '&numberOfDates=01';
  screen.Cursor := crHourGlass;
  try
    lResponse := IdHTTP.Get(requestURL);
    screen.Cursor := crDefault;
  except
    on E: Exception do
    begin
      screen.Cursor := crDefault;
      ShowMessage(E.Message);
    end;
  end;
  IdHTTP.Free;
end;

我们假设我提供了正确的api用户名和密码。当我调用上面的代码时,我收到以下错误: “此服务器无法验证您是否有权访问所请求的文档。 您提供了错误的凭据(例如,密码错误),或者您的浏览器不了解如何提供所需的凭据。“

我做错了什么?有什么建议吗?

1 个答案:

答案 0 :(得分:1)

正如@ElliottFrisch在评论中所述,您没有发送Cookie标题。有两种方法可以做到这一点:

  • 使用CustomHeaders属性:

    IdHTTP.Request.CustomHeaders.AddValue('Cookie', 'OBBasicAuth=fromDialog');
    
  • 使用CookieManager属性伪造实际的Cookie并让TIdHTTP为您生成Cookie标题(请务必事先分配TIdCookieManager组件,并设置TIdHTTP. AllowCookies=True):

    url := TIdURI.Create('https://api.auspost.com.au/DeliveryDates.xml');
    try
      IdHTTP.CookieManager.AddServerCookie('OBBasicAuth=fromDialog', url);
    finally
      url.Free;
    end;
    

您也在泄漏TIdSSLIOHandlerSocketOpenSSL对象。我建议将TIdHTTP指定为Owner。对IdHTTP.Free的调用应该在try..finally中,以获得良好的衡量标准。

试试这个:

procedure RequestDeliveryDate;
var
  IdHTTP: TIdHTTP;
  LHandler: TIdSSLIOHandlerSocketOpenSSL;
  requestURL, query, lResponse: String;
  //url: TIdURI;
begin
  requestURL := 'https://api.auspost.com.au/DeliveryDates.xml';
  query := '?fromPostcode=2000' +
           '&toPostcode=3000' +
           '&networkId=01' +
           '&lodgementDate=2018-02-23' +
           '&numberOfDates=01';

  try
    IdHTTP := TIdHTTP.Create;
    try
      IdHTTP.Request.BasicAuthentication := True;
      IdHTTP.Request.Username := 'your api username';
      IdHTTP.Request.Password := 'your api password';

      IdHTTP.Request.CustomHeaders.AddValue('Cookie', 'OBBasicAuth=fromDialog');    
      {
      url := TIdURI.Create(requestURL);
      try
        IdHTTP.CookieManager.AddServerCookie('OBBasicAuth=fromDialog', url);
      finally
        url.Free;
      end;
      }

      LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
      IdHTTP.IOHandler := LHandler;

      screen.Cursor := crHourGlass;
      try
        lResponse := IdHTTP.Get(requestURL + query);
      finally
        screen.Cursor := crDefault;
      end;
    finally
      IdHTTP.Free;
    end;
  except
    on E: Exception do
      ShowMessage(E.Message);
  end;
end;