拥有以下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用户名和密码。当我调用上面的代码时,我收到以下错误: “此服务器无法验证您是否有权访问所请求的文档。 您提供了错误的凭据(例如,密码错误),或者您的浏览器不了解如何提供所需的凭据。“
我做错了什么?有什么建议吗?
答案 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;