2017-04-22 132 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;