IDHTTP.Post错误 [英] IDHTTP.Post error
问题描述
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文档作为响应.为什么会发生这种情况?我检查了我能在google中找到的所有内容...但是没有任何帮助.
This returns HTTP/1.1 400 Bad Request. If use get from http://priem.edu.ru:8000/import/ImportService.svc/test/import i get right xml document in response. Why could this happen? I checked all i can find in google...but nothing helps.
我正在使用RAD Delphi XE3
Im using RAD Delphi XE3
UPD:测试客户端工作正常... C#+ webclient类.也许对于delphi还有更多的东西...不仅是IdHTTP?
UPD: Test client works fine...C# + webclient class. May be something more exists for delphi...not only IdHTTP?
推荐答案
编辑
事实证明Charset
和ContentType
的分配顺序很重要.
It turned out that the assignment order of the Charset
and ContentType
is important.
如果使用包含xml
,xml-external-parsed-entity
单词或以+xml
结尾的ContentType
,则字符集被强制设置为值'us-ascii'
和'ISO-8859-1'
在其他所有情况下.
If you use a ContentType
containing the xml
, xml-external-parsed-entity
words or ending with +xml
, the Charset is forcibly set to the value 'us-ascii'
and to 'ISO-8859-1'
in all other cases.
该行为没有记录,因此您可以自由地认为它是错误或实现细节.
The behavior is undocumented, so you're free to think it is a bug or an implementation detail.
雷米在TIdEntityHeaderInfo.SetContentType
(IdHTTPHeaderInfo.pas
)正文中的评论说:
Comments from Remy in the body of TIdEntityHeaderInfo.SetContentType
(IdHTTPHeaderInfo.pas
) say:
//RLebeau:根据RFC 3023第3.1、3.3、3.6和8.5节:
//
//如果接收到带有
的text/xml实体,则符合[RFC2046] //省略charset参数,MIME处理器和XML处理器
//必须使用默认字符集值"us-ascii" [ASCII].如果是
//XML MIME实体是通过HTTP传输的,默认
//字符集值仍为"us-ascii". (注意:有一个
//此规范与使用
的HTTP/1.1之间不一致 //由于历史原因,默认将ISO-8859-1 [ISO8859]作为默认值.自
//XML是一种新格式,应选择新的默认值以更好地使用
//I18N.选择了US-ASCII,因为它是UTF-8的交集
//和ISO-8859-1,因为MIME已使用它.)
// RLebeau: per RFC 3023 Sections 3.1, 3.3, 3.6, and 8.5:
//
// Conformant with [RFC2046], if a text/xml entity is received with
// the charset parameter omitted, MIME processors and XML processors
// MUST use the default charset value of "us-ascii"[ASCII]. In cases
// where the XML MIME entity is transmitted via HTTP, the default
// charset value is still "us-ascii". (Note: There is an
// inconsistency between this specification and HTTP/1.1, which uses
// ISO-8859-1[ISO8859] as the default for a historical reason. Since
// XML is a new format, a new default should be chosen for better
// I18N. US-ASCII was chosen, since it is the intersection of UTF-8
// and ISO-8859-1 and since it is already used by MIME.)
要更改字符集,必须在设置ContentType
值之后进行设置,如下所示:
To change the charset, you must set it after setting the ContentType
value, like this:
HTTP.Request.ContentType := 'text/xml';
HTTP.Request.Charset := 'utf-8';
原始答案
(仍然有效)
Original answer
(still valid)
您所指示的内容是用utf-8
编码的,但是Delphi字符串默认是用utf-16
编码的.
You're indicating your content is encoded in utf-8
, but Delphi strings are utf-16
encoded by default.
我手边没有Delphi来检查字符串助手是否具有支持编码的SaveToStream
方法的重载版本,但是我敢打赌,所以可以尝试:
I have no Delphi at hand to check if the string helper have a overloaded version of the SaveToStream
method which supports encodings, but I bet it have, so you can try:
loadData.SaveToStream(Buffer, TEncoding.UTF8);
在发送数据之前.
这篇关于IDHTTP.Post错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!