问题
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;
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.
Im using RAD Delphi XE3
UPD: Test client works fine...C# + webclient class. May be something more exists for delphi...not only IdHTTP?
回答1:
Edit
It turned out that the assignment order of the Charset
and ContentType
is important.
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.
Comments from Remy in the body of TIdEntityHeaderInfo.SetContentType
(IdHTTPHeaderInfo.pas
) say:
// 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.)
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)
You're indicating your content is encoded in utf-8
, but Delphi strings are utf-16
encoded by default.
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);
before sending your data.
回答2:
I found error. If content type is */xml IdHTTP changes Charset to 'us-ansi'... To make this component works properly you need to change
HTTP.Request.Charset := 'utf-8';
HTTP.Request.ContentType := 'text/xml';
to
HTTP.Request.ContentType := 'text/xml; charset=utf-8';
So IdHTTP cant change Charset to us-ansi and you will get encoding you want.
来源:https://stackoverflow.com/questions/15924525/idhttp-post-error