1
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 类。delphi 可能还有更多的东西......不仅仅是IdHTTP?

4

2 回答 2

2

编辑

原来Charsetand的赋值顺序ContentType很重要。

如果您使用ContentType包含xmlxml-external-parsed-entity 字词或以 结尾的a +xml,则 Charset 将被强制设置为该值'us-ascii',并且'ISO-8859-1'在所有其他情况下为。

该行为未记录在案,因此您可以自由地认为它是错误或实现细节。

TIdEntityHeaderInfo.SetContentType( )正文中来自 Remy 的评论IdHTTPHeaderInfo.pas说:

// RLebeau:根据 RFC 3023 第 3.1、3.3、3.6 和 8.5 节:
//
// 符合 [RFC2046],如果接收到 text/xml 实体,
// 字符集参数省略,MIME 处理器和 XML 处理器
//必须使用“us-ascii”[ASCII] 的默认字符集值。在
// XML MIME 实体通过 HTTP 传输的情况下,默认的
// 字符集值仍然是“us-ascii”。(注意:
本规范与 HTTP/1.1 之间存在 // 不一致之处,
由于历史原因,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-8Delphi 字符串是编码的。utf-16

我手头没有 Delphi 来检查字符串助手是否有SaveToStream支持编码的方法的重载版本,但我敢打赌它有,所以你可以尝试:

loadData.SaveToStream(Buffer, TEncoding.UTF8);

在发送您的数据之前。

于 2013-04-11T06:54:14.610 回答
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,您将获得所需的编码。

于 2013-04-11T10:32:02.793 回答