[英]Upload file with form data using Delphi Indy HTTP component
我想使用Indy在Delphi中復制這部分Python代碼:
postdata = {'data': '{"data":{"xMode":0,"overrideOS":1,"messageId":"","vmProfileList":"11","submitType":"0","url":""},"filePriorityQ":"run_now" }'}
file_up = {'amas_filename':open('/home/samples/temp/vtest32.exe','r')}
file_upload_req=requests.post(url,postdata,files=file_up,headers=headers,verify=False)
我試過這樣的:
Params.AddFormField('data', '{"data":{"xMode": '+ xMode +',"analyzeAgain":1,"overrideOS":1,' +
'"vmProfileList":"' + DBProfileID.Value + '","submitType":0,"url":""}}');
Params.AddFile('amas_filename', DBTestFilePath.Value, GetMIMEType(DBTestFilePath.Value));
Params.Position := 0;
HTTP1.Request.ContentType := 'application/x-www-form-urlencoded';
JSON := HTTP1.Post(URL, Params);
但它給了我一個HTTP錯誤“HTTP / 1.0 400錯誤請求”,網絡服務器說“錯誤請求。檢查輸入數據和有效負載大小”。 我知道數據大小足夠小。
這是來自客戶端的請求和來自服務器的響應:
客戶端說
POST /php/fileupload.php HTTP/1.0
Content-Type: multipart/form-data; boundary=--------031317093926335
Content-Length: 248815
VE-SDK-API: <<APIKEYWasHere>>
Host: Server_IP
Accept: application/vnd.ve.v1.0+json
Accept-Encoding: identity
User-Agent: Mozilla/3.0 - NBL
Cookie: PHPSESSID=<<Cookie_Was_Here>>
----------031317093926335
Content-Disposition: form-data; name="data"
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable
{"data":{"xMode": 0,"analyzeAgain":1,"overrideOS":1,"vmProfileList":"2=
4","submitType":0,"url":""},"filePriorityQ":"run_now"}
----------031317093926335
Content-Disposition: form-data; name="amas_filename"; filename="Process.exe"
Content-Type: application/x-msdownload
Content-Transfer-Encoding: binary
MZP
<<FileDataWasHere>>
服務器服務說
HTTP/1.0 400 Bad Request
X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
Cache-Control: no-store, no-cache, must-revalidate, private,max-age=0
Cache-Control: no-store, no-cache, must-revalidate, private,max-age=0
Pragma: no-cache
Pragma: no-cache
Expires: Sat, 26 Jul 1997 05:00:00 GMT
Content-type: text/html; charset=UTF-8
Content-Length: 89
Connection: close
Date: Mon, 13 Mar 2017 06:39:19 GMT
Server: Server FIPS
{"success":false,"errorMessage":"Bad Request. Check input data and payload size(<=200M)"}
我的代碼出了什么問題?
PS:我之前沒有使用表單數據上傳文件。
下次您無法與其他人的API交互時,您應該指明該API實際上是什么,以便人們有機會查找其文檔以查看是否有任何遺漏或錯誤。 在這種情況下,您似乎正在使用McAfee Advanced Threat Defense API 。
在您顯示的HTTP請求中突出顯示的一些事情:
HTTP1.Request.ContentType := 'application/x-www-form-urlencoded';
這是完全錯誤的。 正確的內容類型是multipart/form-data
。 但是, TIdHTTP
在發布TIdMultipartFormDataStream
時會為您處理此TIdMultipartFormDataStream
,因此您根本不需要為Request.ContentType
屬性賦值, TIdHTTP
只會覆蓋它。 但這並沒有改變您的代碼中存在錯誤的事實。
Accept-Encoding: identity
這向我表明您使用的是舊版本的Indy。 您應該考慮升級到更新版本。 除非TIdHTTP.Request.AcceptEncoding
屬性包含其他值,否則TIdHTTP
不再在Accept-Encoding
請求標頭中發送identity
,這不是此處的情況。 某些服務器在請求中明確聲明時無法處理Accept-Encoding: identity
,這就是默認情況下不再發送的原因。
Content-Type: text/plain
您的JSON字段應具有Content-Type
of application/json
,或者甚至可能是此API中的application/vnd.ve.v1.0+json
。 如果沒有另外指定,則默認為text/plain
。 為此, AddFormField()
有一個AContentType
參數。 Web服務器可能對該值敏感。 JSON通常也使用UTF-8編碼,因此您也應該指出它。 為此, AddFormField()
有一個ACharset
參數。
Content-Transfer-Encoding: quoted-printable
您的JSON字符串使用quoted-printable
進行編碼,這通常適用於MIME中的文本內容,但並非所有Web服務器都處理webform提交中的內容,並且它可能不適合非text/...
媒體類型,例如JSON。 AddFormField()
返回TIdFormDataField
對象。 要禁用QP編碼,可以將TIdFormDataField.ContentTransfer
屬性設置為8bit
或binary
。
話雖這么說,嘗試更像這樣的東西:
Params.AddFormField('data', '{"data":{"xMode": ' + xMode + ',"analyzeAgain":1,"overrideOS":1,' +
'"vmProfileList":"' + DBProfileID.Value + '","submitType":0,"url":""}}',
'utf-8',
'application/json'
).ContentTransfer := '8bit';
// using GetMIMEType() to specify the ContentType is redundant as
// AddFile() already does that internally for you using Indy's own
// GetMIMETypeFromFile() function...
Params.AddFile('amas_filename', DBTestFilePath.Value);
JSON := HTTP1.Post(URL, Params);
如果仍然不適合您,我建議您直接與McAfee聯系以獲取進一步的幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.