Delphi firemonkey HTTP 放正文参数
Delphi firemonkey HTTP Put body parameter
在 Delphi FireMonkey 中使用 TIdHTTP.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().'}';
}
});
Delphi 中通过 HTTP posting 数据的过程如下:
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 I Delphi post 字符串流的正确方法是什么?
您没有正确格式化 TStringstream
数据。它甚至不接近 JSON (尽管您的变量名称)。而且您也没有设置 TIdHTTP.Request.ContentType
属性 以便服务器知道您实际发送的数据类型。
如果您阅读 Slim documentation,Slim 支持以下开箱即用的媒体类型:
- application/x-www-form-urlencoded
- application/json
- application/xml & text/xml
您尝试发送的数据最接近 application/x-www-form-urlencoded
。通常使用 TIdHTTP.Post()
而不是 TIdHTTP.Put()
发送,方法是给它一个 TStrings
object 对 name=value
。 Post()
将为您格式化 application/x-www-form-urlencoded
格式的值,并设置 Request.ContentType
属性 匹配。
您的 PHP
期待 PUT
请求而不是 POST
请求。根据 Slim 文档,您实际上可以发送 POST
请求并使其像 PUT
请求一样,通过以下任一方式:
在您的数据中包含一个 _METHOD=PUT
值(仅限 application/x-www-form-urlencoded
)
包括一个 X-HTTP-Method-Override: PUT
HTTP 请求 header(适用于任何媒体类型)。
试试像这样的东西:
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;
另一种方式(没有 Indy),多平台,比 Indy 更好:
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;
在 Delphi FireMonkey 中使用 TIdHTTP.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().'}';
}
});
Delphi 中通过 HTTP posting 数据的过程如下:
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 I Delphi post 字符串流的正确方法是什么?
您没有正确格式化 TStringstream
数据。它甚至不接近 JSON (尽管您的变量名称)。而且您也没有设置 TIdHTTP.Request.ContentType
属性 以便服务器知道您实际发送的数据类型。
如果您阅读 Slim documentation,Slim 支持以下开箱即用的媒体类型:
- application/x-www-form-urlencoded
- application/json
- application/xml & text/xml
您尝试发送的数据最接近 application/x-www-form-urlencoded
。通常使用 TIdHTTP.Post()
而不是 TIdHTTP.Put()
发送,方法是给它一个 TStrings
object 对 name=value
。 Post()
将为您格式化 application/x-www-form-urlencoded
格式的值,并设置 Request.ContentType
属性 匹配。
您的 PHP
期待 PUT
请求而不是 POST
请求。根据 Slim 文档,您实际上可以发送 POST
请求并使其像 PUT
请求一样,通过以下任一方式:
在您的数据中包含一个
_METHOD=PUT
值(仅限application/x-www-form-urlencoded
)包括一个
X-HTTP-Method-Override: PUT
HTTP 请求 header(适用于任何媒体类型)。
试试像这样的东西:
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;
另一种方式(没有 Indy),多平台,比 Indy 更好:
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;