I am trying to access the idHTTP Delphi in a json server without success.
Вы не правильно размещения данных в формате JSON. Вы не можете использовать TStringList
, так как эта версия TIdHTTP.Post()
предназначена для публикации HTML-шаблонов, которые вы не публикуете. Вы должны размещать данные в формате JSON с помощью TStream
вместо этого, например:
procedure TForm4.Button2Click(Sender: TObject);
var
sResponse: string;
EnvStr : TStringStream;
begin
EnvStr := TStringStream.Create(Memo.Text, TEncoding.UTF8);
try
idHTTP.Request.ContentType := 'application/json';
try
sResponse := idHTTP.Post(EditURL.Text, EnvStr);
except
on E: Exception do
ShowMessage('Error on request: '#13#10 + e.Message);
end;
finally
EnvStr.Free;
MemoRet.Text := sResponse;
end;
I've tried all the alternatives and always got the same error: "HTTP/1.1 401 Unauthorized".
Обычно это означает, что сервер запрашивает учетные данные аутентификации, которые вы не предоставляют. Однако в этой ситуации нет заголовка WWW-Authenticate
, присутствующего в ответе сервера, чтобы предоставить информацию о вызове, что явно противоречит спецификации протокола HTTP.
The same format sent in PHP works perfectly
Тогда вам нужно использовать анализатор пакетов, например, Wireshark, чтобы захватить запросы HTTP, вырабатываемого PHP и TIdHTTP
, а затем сравнить их для каких-либо различий, которые вы можете затем код в TIdHTTP
по мере необходимости.
Update: на основе вашего PHP кода, теперь я могу видеть, что ваш код Delphi пытается POST
JSON отформатированную строку, но ваш PHP код вместо POST
ING в HTML веб-форму, содержащую name=value
пары в application/x-www-form-urlencoded
формат. В запросе не участвует JSON. Только ответ использует JSON.
Оглядываясь на это сейчас, код PHP действует на просто массивы, а не на настоящий JSON. Я думаю, вы запутались между ними, потому что представление данных массива выглядит как JSON, но на самом деле это не так. Если вы читаете документацию по PHP, http_build_query()
просто возвращает строку, представляющую строку запроса url HTTP, а затем stream_context_create()
создает поток на основе массива HTTP context options, где строка запроса устанавливается как опция content
, а затем file_get_contents()
отправляет запрос на основе этих параметров - в этом случае запрос HTTP POST
с заголовком access_token
и строкой запроса в качестве тела сообщения. Поскольку заголовок Content-Type
не указан, по умолчанию он равен application/x-www-form-urlencoded
.
Для POST
application/x-www-form-urlencoded
запрос с TIdHTTP
, вы на самом деле были на правильном пути, используя TStringList
с TIdHTTP.Post()
, но вы были заселять TStringList
с неправильным видом данных, и вы не посылая access_token
заголовок, содержащий вашу аутентификацию полномочия.
Следующий код Delphi работает, когда я проверить его:
procedure TForm4.Button2Click(Sender: TObject);
var
sResponse: string;
EnvStr : TStringList;
begin
EnvStr := TStringList.Create;
try
EnvStr.Add('name=TEST');
EnvStr.Add('[email protected]');
EnvStr.Add('phone=1147001211');
EnvStr.Add('mobilePhone=11992329909');
EnvStr.Add('address=Rua Jose Ricardo ');
EnvStr.Add('addressNumber=55');
EnvStr.Add('province=Test');
EnvStr.Add('notificationDisabled=True');
EnvStr.Add('city=Sao Paulo');
EnvStr.Add('state=SP');
EnvStr.Add('country=Brasil');
EnvStr.Add('postalCode=05567210 ');
EnvStr.Add('cpfCnpj=11111111111');
EnvStr.Add('personType=FISICA');
Http.Request.CustomHeaders.Values['access_token'] := '55b3ce85b47629eeee778c0f0c9be450f1b1bc84cc377975f2d3d0d3808a4636';
try
sResponse := idHTTP.Post(EditURL.Text, EnvStr);
except
on E: Exception do
ShowMessage('Error on request: '#13#10 + e.Message);
end;
finally
EnvStr.Free;
MemoRet.Text := sResponse;
end;
end;
Ответ получен:
{"object":"customer","id":"cus_B5HmHFQSMZKD","name":"TEST","email":"[email protected]","company":null,"phone":"1147001211","mobilePhone":"11992329909","address":"Rua Jose Ricardo","addressNumber":"55","complement":null,"province":"Test","postalCode":"05567210","cpfCnpj":"11111111111","personType":"FISICA","deleted":false,"notificationDisabled":true,"city":null,"state":"null","country":"Brasil","foreignCustomer":false,"subscriptions":{"object":"list","hasMore":false,"limit":100,"offset":0,"data":[]},"payments":{"object":"list","hasMore":false,"limit":100,"offset":0,"data":[]},"notifications":{"object":"list","hasMore":false,"limit":100,"offset":0,"data":[{"object":"notification","id":"not_oZV4SlDvdjHf","customer":"cus_B5HmHFQSMZKD","enabled":true,"emailEnabledForProvider":true,"smsEnabledForProvider":false,"emailEnabledForCustomer":true,"smsEnabledForCustomer":true,"event":"PAYMENT_RECEIVED","scheduleOffset":0,"deleted":false},{"object":"notification","id":"not_xNHXDZb4QHqP","customer":"cus_B5HmHFQSMZKD","enabled":true,"emailEnabledForProvider":true,"smsEnabledForProvider":false,"emailEnabledForCustomer":true,"smsEnabledForCustomer":true,"event":"PAYMENT_OVERDUE","scheduleOffset":0,"deleted":false},{"object":"notification","id":"not_yt4BTyQsaRM1","customer":"cus_B5HmHFQSMZKD","enabled":true,"emailEnabledForProvider":false,"smsEnabledForProvider":false,"emailEnabledForCustomer":true,"smsEnabledForCustomer":true,"event":"PAYMENT_DUEDATE_WARNING","scheduleOffset":10,"deleted":false},{"object":"notification","id":"not_LX1vanmAsBy9","customer":"cus_B5HmHFQSMZKD","enabled":true,"emailEnabledForProvider":false,"smsEnabledForProvider":false,"emailEnabledForCustomer":true,"smsEnabledForCustomer":true,"event":"PAYMENT_DUEDATE_WARNING","scheduleOffset":0,"deleted":false},{"object":"notification","id":"not_AyYUHDExa5Zk","customer":"cus_B5HmHFQSMZKD","enabled":true,"emailEnabledForProvider":false,"smsEnabledForProvider":false,"emailEnabledForCustomer":true,"smsEnabledForCustomer":true,"event":"PAYMENT_CREATED","scheduleOffset":0,"deleted":false},{"object":"notification","id":"not_b6NUt9qYZrM2","customer":"cus_B5HmHFQSMZKD","enabled":true,"emailEnabledForProvider":false,"smsEnabledForProvider":false,"emailEnabledForCustomer":true,"smsEnabledForCustomer":true,"event":"PAYMENT_UPDATED","scheduleOffset":0,"deleted":false},{"object":"notification","id":"not_Z4e4SHdXsJaA","customer":"cus_B5HmHFQSMZKD","enabled":true,"emailEnabledForProvider":false,"smsEnabledForProvider":false,"emailEnabledForCustomer":true,"smsEnabledForCustomer":true,"event":"SEND_LINHA_DIGITAVEL","scheduleOffset":0,"deleted":false}]}}
Вы можете использовать HTTP-прокси (Fiddler2, например), чтобы записать запрос на PHP POST и Delphi POST, а затем используйте инструмент diff для сравнения запросов, чтобы найти различия. – mjn
Или вы можете использовать Wireshark, поскольку URL-адрес HTTP, а не HTTPS. В этом случае будет работать любой сниффер пакетов. –
+1 для анализа разницы между запросами PHP и Delphi. Очевидно, что ваш код Delphi не отправляет запрос точно так же, как и работающее PHP-решение, так как если бы вы не получили этот результат. Ваш рабочий пример PHP - ваша лучшая ссылка (и публикация того, что PHP-код в вопросе сравнения может помочь другим определить вашу проблему, если вы не можете этого сделать). – Deltics