在Delphi XE2中通过Indy使用curl

时间:2013-04-10 14:39:12

标签: delphi curl delphi-xe2 indy

我正在尝试使用IdHTTP来对等Delphi XE2中的卷曲操作(已知可行):

 curl http://hub.Healthdata.gov/api/action/datastore_search --data-urlencode '
 {
  "resource_id": "391792b5-9c0a-48a1-918f-2ee63caa1c54",
  "filters": {
    "provider_id": 393303
   }
   }'

我已尝试过以下代码,但它不起作用...有人可以建议更正程序吗? 它回复了糟糕的请求。谢谢。

procedure TfrmMain.get1Click(Sender: TObject);
var
  lHTTP: TIdHTTP;
  lParamList: TStringList;
  result:string;

begin
  lParamList := TStringList.Create;
  lParamList.Add('"resource_id": "391792b5-9c0a-48a1-918f-2ee63caa1c54"');
  lParamList.Add('"filters": {"provider_id": 393303}');

  lHTTP := TIdHTTP.Create(nil);
  try
    Result := lHTTP.Post('http://hub.Healthdata.gov/api/action/datastore_search --data-urlencode ',
     lParamList);
  finally
    FreeAndNil(lHTTP);
    FreeAndNil(lParamList);
  end;
end;

2 个答案:

答案 0 :(得分:1)

--data-urlencode参数不是网址的一部分,它只是告诉curl如何对发布的数据进行编码,因此您根本不会将该部分传递给TIdHTTP

单引号之间curl命令的一部分是要发布的实际数据。 --data-urlencode告诉curl使用HTTP POST方法发送数据,使用application/x-www-form-urlencoded内容类型,并对数据进行网址编码。

TStringsTIdHTTP.Post()完成所有这些操作。通常,application/x-www-form-urlencoded与“name = value”字符串对一起使用,但是curl命令中没有指定名称,只有一个值。如果curl提供了一个默认名称,那么Delphi代码将如下所示:

procedure TfrmMain.get1Click(Sender: TObject);
var
  json: string;
  lHTTP: TIdHTTP;
  lParamList: TStringList;
  result:string;
begin
  json := CRLF +
          '{' + CRLF +
          ' "resource_id": "391792b5-9c0a-48a1-918f-2ee63caa1c54",' + CRLF +
          ' "filters": {' + CRLF +
          '   "provider_id": 393303' + CRLF +
          ' }' + CRLF +
          '}';
  lParamList := TStringList.Create;
  try
    lParamList.Add('somename='+json);
    lHTTP := TIdHTTP.Create(nil);
    try
      Result := lHTTP.Post('http://hub.Healthdata.gov/api/action/datastore_search', lParamList);
    finally
      lHTTP.Free;
    end;
  finally
    lParamList.Free;
  end;
end;

否则,如果curl按原样发送指定的数据,那么Delphi代码将会是这样的:

procedure TfrmMain.get1Click(Sender: TObject);
var
  json: string;
  lHTTP: TIdHTTP;
  lParamList: TStringList;
  result:string;
begin
  json := CRLF +
          '{' + CRLF +
          ' "resource_id": "391792b5-9c0a-48a1-918f-2ee63caa1c54",' + CRLF +
          ' "filters": {' + CRLF +
          '   "provider_id": 393303' + CRLF +
          ' }' + CRLF +
          '}';
  lParamList := TStringList.Create;
  try
    lParamList.Add(json);
    lHTTP := TIdHTTP.Create(nil);
    try
      Result := lHTTP.Post('http://hub.Healthdata.gov/api/action/datastore_search', lParamList);
    finally
      lHTTP.Free;
    end;
  finally
    lParamList.Free;
  end;
end;

唯一的区别是参数值传递给TStringList.Add()

答案 1 :(得分:0)

它们不是网址参数,它只是POST主体的一部分,只是网址编码。

您需要对JSON字符串进行编码并将其写入流,可能是TMemoryStream,然后调用:

TIdHTTP.Post(url,stream);