我正在尝试将POST
应用于Web服务。我需要发送一个类型可变的文件(.docx
,.pdf
,.txt
)以及一个JSON格式的字符串。当使用Indy发布并且文件名包含希腊字符时,文件上传失败
我曾设法与类似下面的代码成功发布文件:
procedure DoRequest;
var
Http: TIdHTTP;
Params: TIdMultipartFormDataStream;
RequestStream, ResponseStream: TStringStream;
JRequest, JResponse: TJSONObject;
url: string;
begin
url := 'some_custom_service'
JRequest := TJSONObject.Create;
JResponse := TJSONObject.Create;
try
JRequest.AddPair('Pair1', 'Value1');
JRequest.AddPair('Pair2', 'Value2');
JRequest.AddPair('Pair3', 'Value3');
Http := TIdHTTP.Create(nil);
ResponseStream := TStringStream.Create;
RequestStream := TStringStream.Create(UTF8Encode(JRequest.ToString));
try
Params := TIdMultipartFormDataStream.Create;
Params.AddFile('File', ceFileName.Text, '').ContentTransfer := '';
Params.AddFormField('Json', 'application/json', '', RequestStream);
Http.Post(url, Params, ResponseStream);
JResponse := TJSONObject.ParseJSONValue(ResponseStream.DataString) as TJSONObject;
finally
RequestStream.Free;
ResponseStream.Free;
Params.Free;
Http.Free;
end;
finally
JRequest.Free;
JResponse.Free;
end;
end;
当我尝试发送包含在文件名希腊字符和空格的文件出现问题。有时会失败,有时会成功。
经过大量的研究,我注意到POST
标头使用EncodeHeader()
函数由Indy的TIdFormDataField
类编码。当帖子失败时,标题中的编码文件名将被拆分,而不是拆分的成功帖子。
例如:
Επιστολή εκπαιδευτικο.docx
被编码为=?UTF-8?B?zpXPgM65z4PPhM6/zrvOriDOtc66z4DOsc65zrTOtc+Fz4TOuc66zr8uZG9j?='#$D#$A' =?UTF-8?B?eA==?=
,其失败。Επιστολή εκπαιδευτικ.docx
编码为=?UTF-8?B?zpXPgM65z4PPhM6/zrvOriDOtc66z4DOsc65zrTOtc+Fz4TOuc66LmRvY3g=?=
,成功。Επιστολή εκπαιδευτικ .docx
编码为=?UTF-8?B?zpXPgM65z4PPhM6/zrvOriDOtc66z4DOsc65zrTOtc+Fz4TOuc66?= .docx
,失败。
我试图要改变文件名的编码,该AddFile()
程序的AContentType
和ContentTransfer
,但这些都不改变行为,我仍然得到错误,当编码的文件名是分裂的。
这是一种错误,还是我错过了什么?
我的代码适用于除上述情况外的每种情况。
我使用Delphi XE3与Indy10。
非常感谢@Remy的回答和所有的解释。我已与服务器所有者联系,我们将尝试一起调试它。与此同时,我尝试了第二种解决方法(8位),并像魅力一样工作。 – stmpakir