procedure Texport_plan.cxB_LoadClick(Sender: TObject);
var
HTTP: TIdHTTP;
Query: String;
Buffer: TMemoryStream;
loadData: Sting;
responseData: String;
begin
try
HTTP := TIdHTTP.Create(nil);
HTTP.Request.ContentEncoding := 'utf-8';
HTTP.Request.ContentType := 'text/xml';
Application.ProcessMessages;
Query := 'http://priem.edu.ru:8000/import/ImportService.svc/import';
loadData := '<Root></Root>'
Buffer := TMemoryStream.Create;
loadData.SaveToStream(Buffer);
responseData := HTTP.Post(Query, Buffer);
except
on E: EIdHTTPProtocolException do
ShowMessage(E.Message);
end;
end;
这将返回HTTP / 1.1 400错误请求。如果使用来自http://priem.edu.ru:8000/import/ImportService.svc/test/import 我得到正确的xml文件作为回应。为什么会这样?我检查了所有我可以在谷歌找到的...但没有任何帮助。
我正在使用RAD Delphi XE3
UPD:测试客户端工作正常... C#+ webclient类。可能是德尔福更存在的东西......不仅仅是IdHTTP?
答案 0 :(得分:2)
修改强>
事实证明,Charset
和ContentType
的分配顺序很重要。
如果您使用包含ContentType
,xml
字或以xml-external-parsed-entity
结尾的+xml
,则会强制将字符集设置为值在所有其他情况下'us-ascii'
和'ISO-8859-1'
。
行为没有记录,因此您可以自由地认为这是一个错误或实现细节。
雷米在TIdEntityHeaderInfo.SetContentType
(IdHTTPHeaderInfo.pas
)正文中的评论说:
// RLebeau:根据RFC 3023第3.1,3.3,3.6和8.5节:
//
//符合[RFC2046],如果收到带有
的text / xml实体 //省略了charset参数,MIME处理器和XML处理器
//必须使用“us-ascii”[ASCII]的默认字符集值。在案件中 //通过HTTP传输XML MIME实体,默认为
// charset值仍然是“us-ascii”。 (注意:有一个 //此规范与使用
的HTTP / 1.1之间的不一致 // ISO-8859-1 [ISO8859]作为历史原因的默认值。由于
// XML是一种新格式,应选择新的默认值以便更好 // I18N选择了US-ASCII,因为它是UTF-8的交集 //和ISO-8859-1,因为它已被MIME使用。)
要更改字符集,必须在设置ContentType
值后设置它,如下所示:
HTTP.Request.ContentType := 'text/xml';
HTTP.Request.Charset := 'utf-8';
原始回答
(仍然有效)
您表示您的内容是以utf-8
编码的,但默认情况下Delphi字符串是utf-16
编码的。
我手边没有Delphi来检查字符串帮助器是否有支持编码的SaveToStream
方法的重载版本,但我敢打赌它有,所以你可以尝试:
loadData.SaveToStream(Buffer, TEncoding.UTF8);
发送数据前。
答案 1 :(得分:0)
我发现了错误。如果内容类型是* / xml IdHTTP将Charset更改为'us-ansi'... 要使此组件正常工作,您需要更改
HTTP.Request.Charset := 'utf-8';
HTTP.Request.ContentType := 'text/xml';
到
HTTP.Request.ContentType := 'text/xml; charset=utf-8';
因此,IdHTTP无法将Charset更改为us-ansi,您将获得所需的编码。