IdHTTP 如何发送 x-www-form-urlencoded body
IdHTTP how to send x-www-form-urlencoded body
我已经在 PostMan 中测试了 POST 函数,使用 body 参数执行 POST 函数,如下所示:
这是 eBay 的此功能文档:
HTTP method: POST
URL (Sandbox): https://api.sandbox.ebay.com/identity/v1/oauth2/token
HTTP headers:
Content-Type = application/x-www-form-urlencoded
Authorization = Basic <B64-encoded-oauth-credentials>
Request body:
grant_type=authorization_code
code=<authorization-code-value>
redirect_uri=<RuName-value>
我的第一次尝试如下:
function udxEBayExchangeAuthCodeForUserToken(AAuthCode: String; AIsProduction: Boolean): String;
var
xRequestBody: TStringStream;
begin
with objHTTP.Request do begin
CustomHeaders.Clear;
ContentType := 'application/x-www-form-urlencoded';
CustomHeaders.Values['Authorization'] := 'Basic ' + 'V2VpbmluZ0MtV2VpbmluZ0M';
end;
xRequestBody := TStringStream.Create('grant_type=' + 'authorization_code' + ','
+ 'code=' + 'v%5E1.1%23i%5E1%23f%5E0%23r%5E1%23I%5E3%23p%5E3' + ','
+ 'redirect_uri=' + 'myredirecturlnameinsandbox',
TEncoding.UTF8);
try
try
Result := objHTTP.Post('https://api.sandbox.ebay.com/identity/v1/oauth2/token', xRequestBody);
except
on E: Exception do
ShowMessage('Error on request: ' + #13#10 + e.Message);
end;
finally
xRequestBody.Free;
end;
end;
第二次尝试使用以下代码 Body
xRequestBody := TStringStream.Create('grant_type=' + 'authorization_code' + '&'
+ 'code=' + AAuthCode + '&'
+ 'redirect_uri=' + gsRuName,
TEncoding.UTF8);
两次尝试都给出 HTTP/1.1 400 Bad Request.
我在 Stack Overflow 上搜索了一下,这是最接近的问题。唯一不同的部分是 POST 的 body。
谁能告诉我分配 POST body 部分的正确方法是什么?
谢谢。
使用 TIdHTTP
发送 application/x-www-form-urlencoded
请求的 首选 方法是使用重载 TIdHTTP.Post()
方法,该方法采用 TStrings
作为输入。您没有以正确的 application/x-www-form-urlencoded
格式发送 TStringStream
数据。
您不需要使用 TIdHTTP.Request.CustomHeaders
属性 来设置 Basic
授权。 TIdHTTP
内置支持 Basic
,只需根据需要使用 TIdHTTP.Request.UserName
和 TIdHTTP.Request.Password
属性,并将 TIdHTTP.Request.BasicAuthentication
属性 设置为 true .
试试这个:
function udxEBayExchangeAuthCodeForUserToken(AAuthCode: String; AIsProduction: Boolean): String;
var
xRequestBody: TStringList;
begin
with objHTTP.Request do
begin
Clear;
ContentType := 'application/x-www-form-urlencoded';
BasicAuthentication := True;
UserName := ...;
Password := ...;
end;
xRequestBody := TStringList.Create;
try
xRequestBody.Add('grant_type=' + 'authorization_code');
xRequestBody.Add('code=' + AAuthCode);
xRequestBody.Add('redirect_uri=' + 'myredirecturlnameinsandbox');
try
Result := objHTTP.Post('https://api.sandbox.ebay.com/identity/v1/oauth2/token', xRequestBody);
except
on E: Exception do
ShowMessage('Error on request: ' + #13#10 + e.Message);
end;
finally
xRequestBody.Free;
end;
end;
如果您想发送自己的 TStringStream
,试试这个:
function udxEBayExchangeAuthCodeForUserToken(AAuthCode: String; AIsProduction: Boolean): String;
var
xRequestBody: TStringStream;
begin
with objHTTP.Request do
begin
Clear;
ContentType := 'application/x-www-form-urlencoded';
BasicAuthentication := True;
UserName := ...;
Password := ...;
end;
xRequestBody := TStringStream.Create('grant_type=' + 'authorization_code' + '&'
+ 'code=' + TIdURI.ParamsEncode(AAuthCode){'v%5E1.1%23i%5E1%23f%5E0%23r%5E1%23I%5E3%23p%5E3'} + '&'
+ 'redirect_uri=' + 'myredirecturlnameinsandbox',
TEncoding.UTF8);
try
try
xRequestBody.Position := 0;
Result := objHTTP.Post('https://api.sandbox.ebay.com/identity/v1/oauth2/token', xRequestBody);
except
on E: Exception do
ShowMessage('Error on request: ' + #13#10 + e.Message);
end;
finally
xRequestBody.Free;
end;
end;
我也被这个问题困扰过,但是解决的不是很有效。后来通过抓包看到了实际发送的内容。给有同样问题的朋友。
function TFormMain.init_web_account(): Boolean;
var
strTmp: Ansistring;
PostStringData: TstringStream;
idhttp1: Tidhttp;
json, json_array1: TQjson;
itype_version: integer;
ifunction_version: integer;
s: string;
url: ansistring;
idMultiPartFormDataStream:TIdMultiPartFormDataStream;
begin
try
result := False;
idhttp1 := TIdHTTP.Create();
PostStringData := TStringStream.Create;
//init_string http://x.x.x.x:8000/user/key?ke1=v1&k2=v2
strTmp := //
'strdogsoftid=' + edtDogNumber.Text + //
'&chipid=' + '' + //
'&status=' + '0' + //
'®_user_name=' + edtRegName.Text + //
'®_init_date=' + formatdatetime('yyyy-mm-dd', dtpRegCodeGenDate.Date) + //
'&lease_expiration=' + formatdatetime('yyyy-mm-dd', dtp_lease_expiration.Date) + //
'&renew_last_date=' + '' + //
'&mobile=' + '' + //
'&weixin=' + '' + //
'&memo=' + '' + //
'&function_version=' + IntToStr(rgVersion.ItemIndex) + //
'&type_version=' + IntToStr(itype_version); //
url := 'http://x.x.x.x:8000/user/' + edtDogNumber.Text;
PostStringData.Clear;
PostStringData.WriteString(strTmp);
try
idhttp1.Request.ContentType := 'application/x-www-form-urlencoded';
s := idhttp1.Post(url, PostStringData);
result := True;
except
on E: Exception do
begin
showmessage(s);
result := False;
exit;
end;
end;
finally
PostStringData.Free;
idhttp1.Free;
end;
end;
如果您使用 TNetHTTPClient,您可以使用“System.Net.Mime”单元通过 HTTP Post 管理多部分表单数据并管理请求。
我用的是Delphi10.4.2
我已经在 PostMan 中测试了 POST 函数,使用 body 参数执行 POST 函数,如下所示:
这是 eBay 的此功能文档:
HTTP method: POST
URL (Sandbox): https://api.sandbox.ebay.com/identity/v1/oauth2/token
HTTP headers:
Content-Type = application/x-www-form-urlencoded
Authorization = Basic <B64-encoded-oauth-credentials>
Request body:
grant_type=authorization_code
code=<authorization-code-value>
redirect_uri=<RuName-value>
我的第一次尝试如下:
function udxEBayExchangeAuthCodeForUserToken(AAuthCode: String; AIsProduction: Boolean): String;
var
xRequestBody: TStringStream;
begin
with objHTTP.Request do begin
CustomHeaders.Clear;
ContentType := 'application/x-www-form-urlencoded';
CustomHeaders.Values['Authorization'] := 'Basic ' + 'V2VpbmluZ0MtV2VpbmluZ0M';
end;
xRequestBody := TStringStream.Create('grant_type=' + 'authorization_code' + ','
+ 'code=' + 'v%5E1.1%23i%5E1%23f%5E0%23r%5E1%23I%5E3%23p%5E3' + ','
+ 'redirect_uri=' + 'myredirecturlnameinsandbox',
TEncoding.UTF8);
try
try
Result := objHTTP.Post('https://api.sandbox.ebay.com/identity/v1/oauth2/token', xRequestBody);
except
on E: Exception do
ShowMessage('Error on request: ' + #13#10 + e.Message);
end;
finally
xRequestBody.Free;
end;
end;
第二次尝试使用以下代码 Body
xRequestBody := TStringStream.Create('grant_type=' + 'authorization_code' + '&'
+ 'code=' + AAuthCode + '&'
+ 'redirect_uri=' + gsRuName,
TEncoding.UTF8);
两次尝试都给出 HTTP/1.1 400 Bad Request.
我在 Stack Overflow 上搜索了一下,这是最接近的问题。唯一不同的部分是 POST 的 body。
谁能告诉我分配 POST body 部分的正确方法是什么? 谢谢。
使用 TIdHTTP
发送 application/x-www-form-urlencoded
请求的 首选 方法是使用重载 TIdHTTP.Post()
方法,该方法采用 TStrings
作为输入。您没有以正确的 application/x-www-form-urlencoded
格式发送 TStringStream
数据。
您不需要使用 TIdHTTP.Request.CustomHeaders
属性 来设置 Basic
授权。 TIdHTTP
内置支持 Basic
,只需根据需要使用 TIdHTTP.Request.UserName
和 TIdHTTP.Request.Password
属性,并将 TIdHTTP.Request.BasicAuthentication
属性 设置为 true .
试试这个:
function udxEBayExchangeAuthCodeForUserToken(AAuthCode: String; AIsProduction: Boolean): String;
var
xRequestBody: TStringList;
begin
with objHTTP.Request do
begin
Clear;
ContentType := 'application/x-www-form-urlencoded';
BasicAuthentication := True;
UserName := ...;
Password := ...;
end;
xRequestBody := TStringList.Create;
try
xRequestBody.Add('grant_type=' + 'authorization_code');
xRequestBody.Add('code=' + AAuthCode);
xRequestBody.Add('redirect_uri=' + 'myredirecturlnameinsandbox');
try
Result := objHTTP.Post('https://api.sandbox.ebay.com/identity/v1/oauth2/token', xRequestBody);
except
on E: Exception do
ShowMessage('Error on request: ' + #13#10 + e.Message);
end;
finally
xRequestBody.Free;
end;
end;
如果您想发送自己的 TStringStream
,试试这个:
function udxEBayExchangeAuthCodeForUserToken(AAuthCode: String; AIsProduction: Boolean): String;
var
xRequestBody: TStringStream;
begin
with objHTTP.Request do
begin
Clear;
ContentType := 'application/x-www-form-urlencoded';
BasicAuthentication := True;
UserName := ...;
Password := ...;
end;
xRequestBody := TStringStream.Create('grant_type=' + 'authorization_code' + '&'
+ 'code=' + TIdURI.ParamsEncode(AAuthCode){'v%5E1.1%23i%5E1%23f%5E0%23r%5E1%23I%5E3%23p%5E3'} + '&'
+ 'redirect_uri=' + 'myredirecturlnameinsandbox',
TEncoding.UTF8);
try
try
xRequestBody.Position := 0;
Result := objHTTP.Post('https://api.sandbox.ebay.com/identity/v1/oauth2/token', xRequestBody);
except
on E: Exception do
ShowMessage('Error on request: ' + #13#10 + e.Message);
end;
finally
xRequestBody.Free;
end;
end;
我也被这个问题困扰过,但是解决的不是很有效。后来通过抓包看到了实际发送的内容。给有同样问题的朋友。
function TFormMain.init_web_account(): Boolean;
var
strTmp: Ansistring;
PostStringData: TstringStream;
idhttp1: Tidhttp;
json, json_array1: TQjson;
itype_version: integer;
ifunction_version: integer;
s: string;
url: ansistring;
idMultiPartFormDataStream:TIdMultiPartFormDataStream;
begin
try
result := False;
idhttp1 := TIdHTTP.Create();
PostStringData := TStringStream.Create;
//init_string http://x.x.x.x:8000/user/key?ke1=v1&k2=v2
strTmp := //
'strdogsoftid=' + edtDogNumber.Text + //
'&chipid=' + '' + //
'&status=' + '0' + //
'®_user_name=' + edtRegName.Text + //
'®_init_date=' + formatdatetime('yyyy-mm-dd', dtpRegCodeGenDate.Date) + //
'&lease_expiration=' + formatdatetime('yyyy-mm-dd', dtp_lease_expiration.Date) + //
'&renew_last_date=' + '' + //
'&mobile=' + '' + //
'&weixin=' + '' + //
'&memo=' + '' + //
'&function_version=' + IntToStr(rgVersion.ItemIndex) + //
'&type_version=' + IntToStr(itype_version); //
url := 'http://x.x.x.x:8000/user/' + edtDogNumber.Text;
PostStringData.Clear;
PostStringData.WriteString(strTmp);
try
idhttp1.Request.ContentType := 'application/x-www-form-urlencoded';
s := idhttp1.Post(url, PostStringData);
result := True;
except
on E: Exception do
begin
showmessage(s);
result := False;
exit;
end;
end;
finally
PostStringData.Free;
idhttp1.Free;
end;
end;
如果您使用 TNetHTTPClient,您可以使用“System.Net.Mime”单元通过 HTTP Post 管理多部分表单数据并管理请求。
我用的是Delphi10.4.2