2017-04-22 68 views
1

在Delphi FireMonkey中使用TIdHTTP.Put()编写字符串流的正确方法是什么?德尔福firemonkey HTTP Put身体参数

我有一个PHP API(超薄)是这样的:

// Update user 
$app->put('/api/user/update/{id}', function(Request $request, Response $response){ 
    $id = $request->getAttribute('id'); 
    $username = $request->getParam('username'); 
    $password = $request->getParam('password'); 
    $nama = $request->getParam('nama'); 
    $alamat = $request->getParam('alamat'); 
    $jenis_kelamin = $request->getParam('jenis_kelamin'); 
    $foto = $request->getParam('foto'); 

    $sql = "UPDATE user SET 
     username = :username, 
     password = :password, 
       nama  = :nama, 
       alamat  = :alamat, 
       jenis_kelamin = :jenis_kelamin, 
       foto  = :foto 
      WHERE id = $id"; 

    try{ 
     // Get DB Object 
     $db = new db(); 
     // Connect 
     $db = $db->connect(); 

     $stmt = $db->prepare($sql); 

     $stmt->bindParam(':username', $username); 
     $stmt->bindParam(':password', $password); 
     $stmt->bindParam(':nama',  $nama); 
     $stmt->bindParam(':alamat',  $alamat); 
     $stmt->bindParam(':jenis_kelamin', $jenis_kelamin); 
     $stmt->bindParam(':foto',  $foto); 

     $stmt->execute(); 

     echo '{"notice": {"text": "Customer Updated"}'; 

    } catch(PDOException $e){ 
     echo '{"error": {"text": '.$e->getMessage().'}'; 
    } 
}); 

为通过HTTP发布数据,德尔福的过程是这样的:

procedure TForm3.updateexample; 
var 
    lHTTP: TIdHTTP; 
    lParamList: TStringList; 
    stream : TStringStream; 
    mydata,json: string; 

begin 


json := 'username='+edtusername.Text+ 
      'password='+edtpassword.Text+ 
      'nama='+edtnama.Text+ 
      'alamat='+edtalamat.Text+ 
      'jenis_kelamin='+cbbjkel.Selected.Text+ 
      'foto="'+edtalamat.text; 

    stream := TStringStream.Create(json,Tencoding.UTF8); 

    //create 
    lHTTP := TIdHTTP.Create(nil); 
    try 

    mydata := lHTTP.put 
     ('http://myweblablalbalbala/api/user/update/'+id,stream); 

    if Pos('Customer Updated', mydata) > 0 then 
    begin 
     ShowMessage('Update Succes'); 
    end 
    else 
     ShowMessage('update fail'); 
    finally 
    lHTTP.Free; 
    lParamList.Free; 
    end; 
end; 

代码工作,但发送后更新,数据从此更改(更新前):

{"id":"1","username":"iboy","password":"123456","nama":"ishak","alamat":"cikupa","jenis_kelamin":"l","foto":"iboy.jpg"} 

到此(更新后):

{"id":"1","username":"","password":"","nama":"","alamat":"","jenis_kelamin":"","foto":""} 

你能帮帮我吗?什么是通过HTTP发布字符串的正确方法?

回答

1

您未正确格式化TStringstream数据。它甚至不接近成为JSON(尽管你的变量名称)。而且您也没有设置TIdHTTP.Request.ContentType属性,因此服务器知道您实际发送的数据类型。

如果你读了Slim documentation,修身支持以下介质类型开箱:

  • 应用程序/ x-WWW窗体-urlencoded
  • 应用/ JSON
  • 应用程序/ XML &文本/ xml

您试图发送的数据最靠近application/x-www-form-urlencoded。通常通过使用TIdHTTP.Post()而不是TIdHTTP.Put()来发送,通过给它一个对的TStrings对象。 Post()将为您格式化application/x-www-form-urlencoded格式的值,并将Request.ContentType属性设置为匹配。

您的PHP期待PUT请求而不是POST请求。每修身文档,你可以实际发送POST请求,并使其像一个PUT要求,有两种方法:

  • ,包括您的数据_METHOD=PUT值(application/x-www-form-urlencoded只)

  • 包括X-HTTP-Method-Override: PUT HTTP请求标头(适用于任何媒体类型)。

尝试更多的东西是这样的:

procedure TForm3.UpdateExample; 
var 
    lHTTP: TIdHTTP; 
    lParamList: TStringList; 
    lReply: string; 
begin 
    lParamList := TStringList.Create; 
    try 
    lParamList.Add('username='+edtusername.Text); 
    lParamList.Add('password='+edtpassword.Text); 
    lParamList.Add('nama='+edtnama.Text); 
    lParamList.Add('alamat='+edtalamat.Text); 
    lParamList.Add('jenis_kelamin='+cbbjkel.Selected.Text); 
    lParamList.Add('foto='+edtalamat.Text); 

    lHTTP := TIdHTTP.Create(nil); 
    try 

     // use one of these, not both! 
     lParamList.Add('_METHOD=PUT'); 
     lHTTP.Request.MethodOverride := 'PUT'; 

     lReply := lHTTP.Post('http://myweblablalbalbala/api/user/update/'+id, lParamList); 

     if Pos('Customer Updated', lReply) > 0 then 
     ShowMessage('Update Success') 
     else 
     ShowMessage('Update Fail'); 
    finally 
     lHTTP.Free; 
    end; 
    finally 
    lParamList.Free; 
    end; 
end; 
+0

像变魔术一样的工作,谢谢 – iboy15

1

另一种方式(无印),多平台,优于同印:

function Upload(const aFilePath: string): boolean; 
var 
    vData: TMultipartFormData; // uses System.Net.Mime 
    vHTTP: THTTPClient; // uses System.Net.HttpClient 
    vCRC: cardinal; 
    vURL: string; 
    vResp: TStringStream; 
begin 
    vURL := 'PHP url'; 
    vResp := TStringStream.Create(''); 
    vData := TMultipartFormData.Create(); 
    vHTTP := THTTPClient.Create; 
    try 
    try 
     vData.AddField('version', MyVerField.ToString); 
     vData.AddField('crc', MyCRC.ToString); 

     vData.AddFile('db_file', aFilePath); 
     Result := vHTTP.Post(vURL, vData, vResp).StatusCode = 200; 

     if Result then 
     Result := vResp.DataString.ContentAsString().Contains('"result":true');   

    except 
     Result := false; 
    end; 
    finally 
    vHTTP.Free; 
    vData.Free; 
    vResp.Free; 
    end; 
end;