IDHTTP.Post错误

时间:2013-04-10 11:25:26

标签: delphi indy idhttp

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?

2 个答案:

答案 0 :(得分:2)

修改

事实证明,CharsetContentType的分配顺序很重要。

如果您使用包含ContentTypexml 或以xml-external-parsed-entity结尾的+xml,则会强制将字符集设置为值在所有其他情况下'us-ascii''ISO-8859-1'

行为没有记录,因此您可以自由地认为这是一个错误或实现细节。

雷米在TIdEntityHeaderInfo.SetContentTypeIdHTTPHeaderInfo.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,您将获得所需的编码。