idHTTP.Post错误HTTP / 1.1 401

时间:2016-01-28 15:45:48

标签: json delphi

我试图在json服务器中访问idHTTP Delphi但没有成功。我已经尝试了所有替代方案并且总是得到相同的错误:“HTTP / 1.1 401 Unauthorized”。

用于测试的JSON格式:

  

{“http”:{“method”:“POST”,“header”:“access_token:55b3ce85b47629eeee778c0f0c9be450f1b1bc84cc377975f2d3d0d3808a4636”,“content”:“name = TEST& email=teste@uol.com& phone = 1147001211& mobilePhone = 11992329909& address = Rua + Jose + Ricardo& addressNumber = 55& province = Test& notificationDisabled = True& city = Sao + Paulo& state = SP& country = Brasil& postalCode = 05567210& cpfCnpj = 11111111111& personType = FISICA“ }}

用于测试的网址:

  

http://homolog.asaas.com/api/v2/customers

测试程序:

procedure TForm4.Button2Click(Sender: TObject);
var
 sResponse: string;
 EnvStr : TStringList;
begin
 EnvStr := TStringList.Create;
 EnvStr.AddStrings(Memo.Lines);
 try
  idHTTP.Request.ContentType := 'application/json';
  idHTTP.Request.Method:='POST';
  idHTTP.Request.AcceptCharSet := 'utf-8';
  try
   sResponse := idHTTP.Post(EditURL.Text,EnvStr);
  except
   on E: Exception do
    ShowMessage('Error on request: '#13#10 + e.Message);
  end;
 finally
  MemoRet.Lines.Clear;
  MemoRet.Lines.add(sResponse);
 end;
end;

在PHP中发送的格式完全相同,但是使用idHTTP会返回错误:“HTTP / 1.1 401 Unauthorized”。

PHP完美运行

<?php
 $api_url = "http://homolog.asaas.com/api/v2";   
 $api_key = "55b3ce85b47629eeee778c0f0c9be450f1b1bc84cc377975f2d3d0d3808a4636";
 $url_cus = $api_url."/customers";
 $param = array(
'name' => utf8_encode('Test'),
'email' => 'test@uol.com.br',
'phone' => '1147001211',
'mobilePhone' => '11992329909',
'address' => utf8_encode('Rua Jose Ricardo'),
'addressNumber' => '55',
'province' => 'Test',
'notificationDisabled' => 'True',
'city' => 'Sao Paulo',
'state' =>'SP',
'country' => 'Brasil',
'postalCode' => '05567210',
'cpfCnpj' => '11111111111',
'personType' => 'FISICA'
  );
 $req = http_build_query($param);
 $ctx = stream_context_create(
 array(
       "http" => array(
       "method" => "POST",
       "header" => "access_token: $api_key",
       "content" => $req
        )
      )
     );

 $res = file_get_contents($url_cus, true, $ctx);

 //PHP Object
 $obj = json_decode($res);

 //get id of register 
 $id=utf8_decode("$obj->id");

 // return result
 // return $id;

?>

1 个答案:

答案 0 :(得分:1)

  

我试图在json服务器中访问idHTTP Delphi但没有成功。

您没有正确发布JSON数据。您无法使用TStringList,因为该TIdHTTP.Post()版本用于发布您未发布的HTML网络表单。您需要使用TStream发布JSON数据,例如:

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;
  

我已经尝试了所有替代方案并且总是遇到同样的错误:&#34; HTTP / 1.1 401未经授权&#34;。

通常这意味着服务器要求您提供身份验证凭据。但是,在这种情况下,服务器响应中没有WWW-Authenticate标头提供质询信息,这明显违反了HTTP协议规范。

  

PHP中发送的相同格式完美无缺

然后,您需要使用数据包嗅探器(如Wireshark)来捕获由PHP和TIdHTTP生成的HTTP请求,然后将它们与您可以编码为TIdHTTP的任何差异进行比较。需要的。

更新:基于您的PHP代码,我现在可以看到您的Delphi代码正在尝试POST一个JSON格式的字符串,但您的PHP代码却是POSTname=value格式包含application/x-www-form-urlencoded对的HTML网络表单。请求中根本没有涉及JSON。只有响应使用JSON。

现在回过头来看,PHP代码只是简单的数组,而不是真正的JSON。我认为你们在两者之间感到困惑,因为数组数据的表示看起来像JSON但实际上并非如此。如果你阅读PHP文档,http_build_query()只返回一个表示HTTP url查询字符串的字符串,然后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 procedure TForm4.Button2Click(Sender: TObject); var sResponse: string; EnvStr : TStringList; begin EnvStr := TStringList.Create; try EnvStr.Add('name=TEST'); EnvStr.Add('email=teste@uol.com'); 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; {{1}} {}} {{1}}包含错误类型的数据,并且您没有发送包含身份验证凭据的{{1}}标头。

以下Delphi代码在我测试时起作用:

{{1}}

收到回复:

  

{&#34;对象&#34;:&#34;顾客&#34;&#34; ID&#34;:&#34; cus_B5HmHFQSMZKD&#34;&#34;名称&#34;:& #34;测试&#34;&#34;电子邮件&#34;:&#34; teste@uol.com",&#34;公司&#34;:无效,&#34;电话&#34 ;: &#34; 1147001211&#34;,&#34; mobilePhone&#34;:&#34; 11992329909&#34;,&#34;地址&#34;:&#34; Rua Jose Ricardo&#34;,&#34; ; addressNumber&#34;:&#34; 55&#34;&#34;补充&#34;:无效,&#34;全省&#34;:&#34;测试&#34;&#34; POSTALCODE&# 34;:&#34; 05567210&#34;&#34; cpfCnpj&#34;:&#34; 11111111111&#34;&#34; personType&#34;:&#34; FISICA&#34;&# 34;删除&#34;:假,&#34; notificationDisabled&#34;:真,&#34;城市&#34;:无效,&#34;状态&#34;:&#34;零&#34;,& #34;国家&#34;:&#34;巴西&#34;&#34; foreignCustomer&#34;:假,&#34;订阅&#34; {&#34;对象&#34;:&#34 ;列表&#34;&#34; hasMore&#34;:假,&#34;限制&#34;:100,&#34;偏移&#34;:0,&#34;数据&#34;:[] },&#34;支付&#34; {&#34;对象&#34;:&#34;列表&#34;&#34; hasMore&#34;:假,&#34;限制&#34 ;: 100,&#34;偏移&#34;:0,&#34;数据&#34;:[]},&#34;通知&#34; {&#34; objec T&#34;:&#34;列表&#34;&#34; hasMore&#34;:假,&#34;限制&#34;:100,&#34;偏移&#34;:0,&#34 ;数据&#34;:[{&#34;对象&#34;:&#34;通知&#34;&#34; ID&#34;:&#34; not_oZV4SlDvdjHf&#34;&#34;顾客&# 34;:&#34; cus_B5HmHFQSMZKD&#34;&#34;启用&#34;:真,&#34; emailEnabledForProvider&#34;:真,&#34; smsEnabledForProvider&#34;:假,&#34; emailEnabledForCustomer& #34;:真,&#34; smsEnabledForCustomer&#34;:真,&#34;事件&#34;:&#34; PAYMENT_RECEIVED&#34;&#34; scheduleOffset&#34;:0,&#34;删除&#34;:假},{&#34;对象&#34;:&#34;通知&#34;&#34; ID&#34;:&#34; not_xNHXDZb4QHqP&#34;&#34;顾客& #34;:&#34; cus_B5HmHFQSMZKD&#34;&#34;启用&#34;:真,&#34; emailEnabledForProvider&#34;:真,&#34; smsEnabledForProvider&#34;:假,&#34; emailEnabledForCustomer&#34;:真,&#34; smsEnabledForCustomer&#34;:真,&#34;事件&#34;:&#34; PAYMENT_OVERDUE&#34;&#34; scheduleOffset&#34;:0,&#34 ;删除&#34;:假},{&#34;对象&#34;:&#34;通知&#34;&#34; ID&#34;:&#34; not_yt4BTyQsaRM1&#34;&#34;顾客&#34;:&#34 ; cus_B5HmHFQSMZKD&#34;&#34;启用&#34;:真,&#34; emailEnabledForProvider&#34;:假,&#34; smsEnabledForProvider&#34;:假,&#34; emailEnabledForCustomer&#34;:真, &#34; smsEnabledForCustomer&#34;:真,&#34;事件&#34;:&#34; PAYMENT_DUEDATE_WARNING&#34;&#34; scheduleOffset&#34;:10,&#34;删除&#34;:假},{&#34;对象&#34;:&#34;通知&#34;&#34; ID&#34;:&#34; not_LX1vanmAsBy9&#34;&#34;顾客&#34;:&# 34; cus_B5HmHFQSMZKD&#34;&#34;启用&#34;:真,&#34; emailEnabledForProvider&#34;:假,&#34; smsEnabledForProvider&#34;:假,&#34; emailEnabledForCustomer&#34;:真&#34; smsEnabledForCustomer&#34;:真,&#34;事件&#34;:&#34; PAYMENT_DUEDATE_WARNING&#34;&#34; scheduleOffset&#34;:0,&#34;删除&#34 ;:假},{&#34;对象&#34;:&#34;通知&#34;&#34; ID&#34;:&#34; not_AyYUHDExa5Zk&#34;&#34;顾客&#34;:& #34; cus_B5HmHFQSMZKD&#34;&#34;启用&#34;:真,&#34; emailEnabledForProvider&#34;:假,&#34; smsEnabledForProvider&#34;:假,&#34; emailEnabledForCustomer&#34 ;:真,#&34; smsEnabledForCustom ER&#34;:真,&#34;事件&#34;:&#34; PAYMENT_CREATED&#34;&#34; scheduleOffset&#34;:0,&#34;删除&#34;:假},{& #34;对象&#34;:&#34;通知&#34;&#34; ID&#34;:&#34; not_b6NUt9qYZrM2&#34;&#34;顾客&#34;:&#34; cus_B5HmHFQSMZKD&# 34;,&#34;启用&#34;:真,&#34; emailEnabledForProvider&#34;:假,&#34; smsEnabledForProvider&#34;:假,&#34; emailEnabledForCustomer&#34;:真,&#34 ; smsEnabledForCustomer&#34;:真,&#34;事件&#34;:&#34; PAYMENT_UPDATED&#34;&#34; scheduleOffset&#34;:0,&#34;删除&#34;:假},{ &#34;对象&#34;:&#34;通知&#34;&#34; ID&#34;:&#34; not_Z4e4SHdXsJaA&#34;&#34;顾客&#34;:&#34; cus_B5HmHFQSMZKD& #34;&#34;启用&#34;:真,&#34; emailEnabledForProvider&#34;:假,&#34; smsEnabledForProvider&#34;:假,&#34; emailEnabledForCustomer&#34;:真,&# 34; smsEnabledForCustomer&#34;:真,&#34;事件&#34;:&#34; SEND_LINHA_DIGITAVEL&#34;&#34; scheduleOffset&#34;:0,&#34;删除&#34;:假}] }}