java - https请求从java到delphi的翻译

标签 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 用户名和密码。当我调用上面的代码时,出现以下错误: “该服务器无法验证您是否有权访问所请求的文档。 您提供了错误的凭据(例如,错误的密码),或者您的浏览器不了解如何提供所需的凭据。”

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

最佳答案

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

  • 使用CustomHeaders属性:

    IdHTTP.Request.CustomHeaders.AddValue('Cookie', 'OBBasicAuth=fromDialog');
    
  • 使用 CookieManager 属性伪造一个实际的 cookie,并让 TIdHTTP 为您生成 Cookie header (请务必分配预先创建一个 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; 

关于java - https请求从java到delphi的翻译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48949353/

相关文章:

java - 如何从通用双向链表中删除

delphi - 表单 :Transparent, 表单 :non Transparent? 上的控件

delphi - 如何通过 idHTTP 获取(即读取)https 响应。通常是 REST 授权

http - IdHTTP 如何发送原始正文

java - 在 webdriver 中使用 log.error 捕获没有此类元素?

java - Android如何检测网络类型改变事件?

Delphi - 记录所有 HTTP 请求

delphi - TIdHTTP 和 TLS SNI 不起作用

java - 进行强制转换时出现运行时异常

delphi - 终止一个 'sleeping' 线程