有以下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/