Delphi IDHTTP.Post错误 procedure Texport\u plan.cxB\u LoadClick(发送方:TObject); 变量 HTTP:TIdHTTP; 查询:字符串; 缓冲区:TMemoryStream; 载荷数据:Sting; 响应数据:字符串; 开始 尝试 HTTP:=TIdHTTP.Create(nil); HTTP.Request.ContentEncoding:=“utf-8”; HTTP.Request.ContentType:=“text/xml”; Application.ProcessMessages; 查询:='http://priem.edu.ru:8000/import/ImportService.svc/import'; 加载数据:='' 缓冲区:=TMemoryStream.Create; loadData.SaveToStream(缓冲区); responseData:=HTTP.Post(查询、缓冲区); 除了 关于E:EIdHTTPProtocolException do ShowMessage(E.Message); 结束; 结束;

Delphi IDHTTP.Post错误 procedure Texport\u plan.cxB\u LoadClick(发送方:TObject); 变量 HTTP:TIdHTTP; 查询:字符串; 缓冲区:TMemoryStream; 载荷数据:Sting; 响应数据:字符串; 开始 尝试 HTTP:=TIdHTTP.Create(nil); HTTP.Request.ContentEncoding:=“utf-8”; HTTP.Request.ContentType:=“text/xml”; Application.ProcessMessages; 查询:='http://priem.edu.ru:8000/import/ImportService.svc/import'; 加载数据:='' 缓冲区:=TMemoryStream.Create; loadData.SaveToStream(缓冲区); responseData:=HTTP.Post(查询、缓冲区); 除了 关于E:EIdHTTPProtocolException do ShowMessage(E.Message); 结束; 结束;,delphi,indy,idhttp,Delphi,Indy,Idhttp,这将返回HTTP/1.1400错误请求。如果使用从 我得到了正确的xml文档作为响应。为什么会发生这种情况?我在谷歌上查了所有我能找到的东西…但没有任何帮助 我正在使用raddelphixe3 UPD:测试客户端工作正常…C#+webclient类。delphi可能还有更多的功能…不仅仅是IdHTTP?编辑 原来Charset和ContentType的赋值顺序很重要 如果使用包含xml、xml外部解析实体的ContentType单词或以+xml结尾,则在所有其他情况下,字符集将强制设置为值'us

这将返回HTTP/1.1400错误请求。如果使用从 我得到了正确的xml文档作为响应。为什么会发生这种情况?我在谷歌上查了所有我能找到的东西…但没有任何帮助

我正在使用raddelphixe3

UPD:测试客户端工作正常…C#+webclient类。delphi可能还有更多的功能…不仅仅是IdHTTP?

编辑

原来
Charset
ContentType
的赋值顺序很重要

如果使用包含
xml
xml外部解析实体的
ContentType
单词或以
+xml
结尾,则在所有其他情况下,字符集将强制设置为值
'us-ascii'
,并设置为
'ISO-8859-1'

该行为没有文档记录,因此您可以自由地认为它是一个bug或一个实现细节

Remy在
tidentyheaderinfo.SetContentType
IdHTTPHeaderInfo.pas
)正文中的评论说:

//RLEBAU:根据RFC 3023第3.1、3.3、3.6和8.5节:
//
//与[RFC2046]一致,如果接收到带有
的文本/xml实体 //省略了字符集参数,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已经使用了它。)

要更改字符集,必须在设置
ContentType
值后进行设置,如下所示:

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;
原始答案
(仍然有效)

您表示您的内容是以
utf-8
编码的,但默认情况下Delphi字符串是
utf-16
编码的

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

HTTP.Request.ContentType := 'text/xml';
HTTP.Request.Charset := 'utf-8';

在发送数据之前。

我发现错误。如果内容类型为*/xml IdHTTP将字符集更改为“us ansi”。。。 要使此组件正常工作,您需要更改

loadData.SaveToStream(Buffer, TEncoding.UTF8);


因此IdHTTP无法将字符集更改为us ansi,您将获得所需的编码。

您是否尝试将其发送到?您是否尝试通过XML验证器将loadData放入?该站点声称它必须在输入时获取XML,所以给它XML,而不是SGMLValidate不是XML validator=)它检查标记中的数据是否正确=)添加任何更改=(他们有他们的测试客户端…它可以与或一起工作?大概是因为你发送了一个错误的请求。你有一个可以工作的测试程序。使用Wire Shark来观察来自该程序的一个好请求和来自你的一个坏请求。它们之间有什么不同,如何使你的行为更像一个好的请求?我知道。)之前我已经检查过了。再次检查…没有结果。最有趣的是,来自测试客户机和我的程序的包是相等的,除了:标识、序列号、确认号和Src端口。在我启动了几次测试客户机之后,我可以看到…只有源端口是常量。所以这可能只是一个问题…但对我来说,它不是我从哪个端口发送数据真的很重要。嗯…更改顺序真的很有帮助…Tnx提供了这个建议。关于ansi ascii,我犯了一个错误…你说得对。我会把你的答案标记为最佳。-1因为你称愚蠢的组件为免费组件。如果你资助了一个错误,你就去找项目开发人员,感谢他们的努力并通知他们关于你的发现,它是如何错误的,以及如何解决它。我花了2天的时间来找到这个东西。它不是一个bug…它是这样编码的。我不认为如果'xml',那么:=ansi是一个错误…顺便说一句…我想你会同意的…如果你键入某物:='xxx',那么你希望xxx不是yyy,没有任何理由如果它是这样编码的,或者它是一个错误bug,或者是因为某些RFC规则。Indy团队的Remy通常非常了解这一点。而且,信不信由你,你免费获得了Indy,因为它是一个开源项目。它包含在标准Embarcadero安装中这一事实并不使它成为你购买的产品的一部分。有关更多信息,请访问Indy,你能告诉我Indy在哪里做吗您描述的更改?快速搜索
us ansi
/xml
无法从Indy源代码中检索到任何内容。我找到了它,查看代码发现赋值顺序很重要,强制设置的字符集是
us ascii
(而不是您所说的
us ansi
)该行为是未记录的,因此您可以认为它是一个bug或只是一个实现细节。所有的原因都是在代码> TytTyTythEnrimeNo.StCuttType < /Cult>方法体(IDHTHTPHEADEFIL.PAS)的注释中。反转分配顺序,不要使用您建议的任务(全部是内容类型)。因为其他印地群岛的部分可能取决于该地产的价值,并且被认为是你的
HTTP.Request.Charset := 'utf-8';
HTTP.Request.ContentType := 'text/xml';
HTTP.Request.ContentType := 'text/xml; charset=utf-8';