德尔福和沃尔玛批量 API 上传 - 内部服务器错误



我正在使用Delphi XE5,我正在尝试使用批量API上传将商品发送到沃尔玛,但我正在努力与沃尔玛的服务器建立正确的连接。 我已经在这里检查了一些类似的问题,例如沃尔玛API - 有效负载哑剧类型问题

最奇怪的是,沃尔玛实际上接受了该提要(我在提要列表中看到了它),但我收到内部服务器错误,然后是无意义的字符(可能是编码类型或只是一种错误),例如

(#$D#$A#$1F#$008B#8#0#0#0#0#0#0#3#$D'A±'#$D#$0080'0'#$C#4'AU~'#2'v ?d'#$0087#4'?#1#$0091'OE'#$E#$008A'O'#$1E'®?O?'#$18#$0091#$A#$0091'M^'#$C'?;'#$1D'G'#$A'dR±U?oip?m'#$1A'AVS'#4#$16'R?iR'#$1B#$0095'RO?}u'#0'enIjM'#0#0#0)

所以我使用IndyIdHTTP,我尝试使用TIdMultipartFormDataStream,并且还自己创建有效负载,同时收到内部服务器错误。 我想我以某种方式破坏了他们的解析器,因为如果我在开始时错过了一个 CR LF (#13#10),我会得到一个特定的错误

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns2:errors xmlns:ns2="http://walmart.com/"><ns2:error><ns2:code>SYSTEM_ERROR.GMP_GATEWAY_API</ns2:code><ns2:field>PDR-0012</ns2:field><ns2:description></ns2:description><ns2:info>System encountered some internal error.</ns2:info><ns2:severity>ERROR</ns2:severity><ns2:category>SYSTEM</ns2:category><ns2:causes/><ns2:errorIdentifiers/></ns2:error></ns2:errors>

如果我在末尾添加额外的 CRLF,则会收到另一个错误,指出请求中有多个提要。 所以我真的假设有一些东西使该服务器/解析器返回内部错误,但我没有得到什么,我再次重复提要实际上被接受,然后在我收到此错误的情况下被服务器处理。

下面是一个示例请求,其中包含我自己创建的有效负载:

POST /v3/feeds?feedType=item HTTP/1.1
Content-Type: multipart/form-data; boundary=qwerty
Content-Length: 5077
WM_SVC.NAME: Walmart Marketplace
WM_QOS.CORRELATION_ID: {67F0E2F9-5EAC-4E8C-9C90-650D8F7B3B7A}
WM_SEC.TIMESTAMP: 1528364885909
WM_SEC.AUTH_SIGNATURE: nSHgqzPOtzSR4wJU+U/vQJk+rk6Ke2QwodTHjzkjau2BonXZxiU9e+3NFPzaat2OUyc+vr0jqRk0H0QWTSC21PrI87mvqei5UJCJwNiIx0zVjAGpxsnIuvtIKkQsBpuUAa8C6SjTiTpDRsNt4IOxrk+tLWxlwQubWVCV+009a6o=
WM_CONSUMER.ID: 16248274-1f53-4e6d-880e-b5417698b878
WM_CONSUMER.CHANNEL.TYPE: 0f3e4dd4-0514-4346-b39d-af0e00ea066d
Host: marketplace.walmartapis.com
Accept: application/xml, */*
Accept-Encoding: identity
Accept-Language: en-US
User-Agent: Mozilla/3.0 (compatible; Indy Library)

请求

--qwerty
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<MPItemFeed xmlns:ns2="http://walmart.com/">
<MPItemFeedHeader>
<version>3.1</version>
<requestId>{694A5564-7E8E-46C7-B772-C944A8C9CF99}</requestId>
<mart>WALMART_US</mart>
</MPItemFeedHeader>
<MPItem>
<processMode>REPLACE_ALL</processMode>
<sku>w-cc-a1-4pk-white-l</sku>
<productIdentifiers>
<productIdentifier>
<productIdType>UPC</productIdType>
<productId>192082276845</productId>
</productIdentifier>
</productIdentifiers>
<MPProduct>
<SkuUpdate>Yes</SkuUpdate>
<productName>Caramel Cantina 4 Pack Sleeping Nursing Cross Front Maternity Bra (Large, White)</productName>
<ProductIdUpdate>Yes</ProductIdUpdate>
<category>
<ClothingCategory>
<Clothing>
<shortDescription>Stretchy comfort cross front sleep bra by Caramel Cantina. Whether for nursing / maternity or for wearing as a sleep bra (or both nursing and sleep bras) - you&apos;ll experience a wire free regular back strap sleep bra. This mid-weight fabric but light support wireless bra is great for all day wear and comfort.  The straps are wider than a standard bra - offering a longer range of wear time.   Great for wearing indoors (ie when you&apos;re kicking around the home or going to bed). These are padless - most moms use their own favorite nursing pads with these (though no pads are included). The front cups have two layers of fabric to add a bit more support (though we still call them our light support comfort bra). The criss cross front style allows for easy access while nursing your baby. 92% Nylon 8% Spandex fabric washes up nicely.  Cool wash and cool dry. Hang dry for longer life. The straps narrowest point at the shoulders are 1.25-1.5 inches (depending on the size). The bras are super stretchy - if you&apos;re looking for something super supportive (ie - they pull you in really tight - more like a sports bra) these probably aren&apos;t what you&apos;re looking for.  Not recommended for heavy sports activity. Best worn for activities such as walking, sleeping, lounging, light activity, running errands, etc.</shortDescription>
<keyFeatures>
<keyFeaturesValue>4 Pack Includes 4 Bras of the Same Design - Color Option Above</keyFeaturesValue>
<keyFeaturesValue>Soft Cup - Front Double Layered - No padding - Wireless</keyFeaturesValue>
<keyFeaturesValue>Super Soft Sleep In Style Bra - Great for Nursing or Sleeping</keyFeaturesValue>
<keyFeaturesValue>Criss Cross Front Design Gives Easy Nursing Access</keyFeaturesValue>
<keyFeaturesValue>Regular Straps - Scoop Back Design - Strap Width 1.25-1.5 Inches Depending on Size</keyFeaturesValue>
</keyFeatures>
<brand>Caramel Cantina</brand>
<mainImageUrl>https://www.dancecheerskate.com/_inv/D54173DB8F934DB2A4C68D24FAC087F5/wm-cc-a1-4pk-white.jpg</mainImageUrl>
<productSecondaryImageURL>
<productSecondaryImageURLValue>https://www.dancecheerskate.com/_inv/D54173DB8F934DB2A4C68D24FAC087F5/wm-cc-a1-wht-m1.jpg</productSecondaryImageURLValue>
</productSecondaryImageURL>
<color>White</color>
<clothingSize>Large</clothingSize>
<variantGroupId>cc-a1-4pk-parent</variantGroupId>
<variantAttributeNames>
<variantAttributeName>color</variantAttributeName>
<variantAttributeName>clothingSize</variantAttributeName>
</variantAttributeNames>
<countryOfOriginTextiles>Imported</countryOfOriginTextiles>
<fabricCareInstructions>
<fabricCareInstruction>Machine wash cold gentle cycle with like colors. Hang Dry. Do Not Bleach. Do Not Iron.</fabricCareInstruction>
</fabricCareInstructions>
<multipackQuantity>1</multipackQuantity>
<countPerPack>4</countPerPack>
<count>4</count>
<pattern>Solid</pattern>
<material>Nylon; Spandex</material>
<gender>Female</gender>
<ageGroup>
<ageGroupValue>Adult</ageGroupValue>
</ageGroup>
<clothingSizeGroup>Maternity</clothingSizeGroup>
<isSet>No</isSet>
<requiresTextileActLabeling>Yes</requiresTextileActLabeling>
<clothingTopStyle>Sleep Bra</clothingTopStyle>
<upperBodyStrapConfiguration>Regular</upperBodyStrapConfiguration>
<braStyle>Nursing</braStyle>
<clothingStyle>Maternity</clothingStyle>
<clothingFit>Maternity</clothingFit>
<isMaternity>Yes</isMaternity>
<swatchImages>
<swatchImage>
<swatchVariantAttribute>color</swatchVariantAttribute>
<swatchImageUrl>https://www.dancecheerskate.com/_inv/D54173DB8F934DB2A4C68D24FAC087F5/wm-cc-a1-4pk-white.jpg</swatchImageUrl>
</swatchImage>
</swatchImages>
</Clothing>
</ClothingCategory>
</category>
</MPProduct>
<MPOffer>
<price>25.00</price>
<ShippingWeight>
<measure>11.80</measure>
<unit>lb</unit>
</ShippingWeight>
<ProductTaxCode>2038895</ProductTaxCode>
</MPOffer>
</MPItem>
</MPItemFeed>
--qwerty--

我得到的回复如下

HTTP/1.1 500 Internal Server Error
Method: null
URI: null
WM_CONSUMER.ID: 16248274-1f53-4e6d-880e-b5417698b878
WM_CONSUMER.INTIMESTAMP: 
WM_QOS.CORRELATION_ID: {67F0E2F9-5EAC-4E8C-9C90-650D8F7B3B7A}
WM_SEC.AUTH_TOKEN: 
WM_SEC.REFRESH_AUTH_TOKEN: 
WM_SVC.CLASS_NAME: com.walmart.services.impl.GMPGatewayService$$EnhancerBySpringCGLIB$$c88958a9
WM_SVC.ENV: prod
WM_SVC.INTIMESTAMP: 1528364905439
WM_SVC.METHOD_NAME: doPostMultiPart
WM_SVC.NAME: Walmart Marketplace
WM_SVC.OUTTIMESTAMP: 1528364905567
WM_SVC.SERVER_IP: 10.65.34.219
WM_SVC.SERVER_NAME: PartnerGMPService-5480119-4-96141283
WM_SVC.VERSION: 
X-Powered-By: soari-interceptors-4.4.4
Content-Type: text/plain
Cteonnt-Length: 77
Server: web
Content-Encoding: gzip
Content-Length: 89
Expires: Thu, 07 Jun 2018 09:48:25 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 07 Jun 2018 09:48:25 GMT
Connection: close

然后是上面的那些角色。请注意Cteonnt-Length: 77标题,这不是我的错别字,它只是以这种方式出现。

根据支持,他们成功地使用以下标头并要求我使用它们,但我看不出我所做的有任何区别

WM_SVC.NAME:Walmart Marketplace
WM_QOS.CORRELATION_ID:123456abcdef
WM_SEC.AUTH_SIGNATURE:TnjevCf+voP9dmnafuCTFruwq6leBuAihSvag89WLieDRBsz7aULxgEqV71ZjIp572wVYPI07y6tdMutNLklDGwxvNdlJ2Q2xGvUIqjVPtqlhdcWvsmgqdpio7puQ4G03q1lReWzTquKecDEbB1ztH6ukj9F5rMe7d7PH8QkFsY=
WM_SEC.TIMESTAMP:1528152581896
WM_CONSUMER.ID:16248274-1f53-4e6d-880e-b5417698b878
WM_CONSUMER.CHANNEL.TYPE:0f3e4dd4-0514-4346-b39d-af0e00ea066d
Accept:application/xml
Host:marketplace.walmartapis.com
Content-Type:multipart/form-data

我已经与eBay,亚马逊,PayPal,Magento等进行了成功的沟通,但在这里显然我错过了一些东西,真的不知道如何解决它。

感谢您阅读本文,希望有人能提供这里发生的事情的线索。

编辑我正在根据需要添加一些德尔菲代码

版本 1 不带TIdMultipartFormDataStream

function TdmSyncWallmart.CreateItemFeed(aIDPlatforms: String; aLastChanged,
aCurrDate: TDateTime; var aReqID: String): TStringStream;
var
aXML: TNativeXML;
aNode: TXmlNode;
aItemNode: TXmlNode;
aCatNode: TXmlNode;
aTmpNode: TXmlNode;
aShortDesc: String;
i: Integer;
aIDItems: String;
begin
Result := nil;
dstListPlatformsSyncItemsWallmart.Close;
dstListPlatformsSyncItemsWallmart.Parameters.ParamByName('@IDPlatforms').Value := aIDPlatforms;
dstListPlatformsSyncItemsWallmart.Parameters.ParamByName('@LastChanged').Value := aLastChanged;
dstListPlatformsSyncItemsWallmart.Parameters.ParamByName('@CurrDate').Value := aCurrDate;
dstListPlatformsSyncItemsWallmart.Open;
if dstListPlatformsSyncItemsWallmart.IsEmpty then
Exit;
aReqID := GenGuid;
aXML := TNativeXml.CreateName('MPItemFeed');
try
aXML.Declaration.AttributeAdd('standalone', 'yes');
aXML.Root.AttributeAdd('xmlns:ns2', 'http://walmart.com/');
//Header
aNode := aXML.Root.NodeNew('MPItemFeedHeader');
with aNode.NodeNew('version') do
Value := '3.1';
with aNode.NodeNew('requestId') do
Value := aReqID;
with aNode.NodeNew('mart') do
Value := 'WALMART_US';
//... some code for generating the XML
Result := TStringStream.Create;
aXML.XmlFormat := xfReadable;
Result.WriteString('--qwerty'#13#10#13#10{'Content-Disposition: form-data; filename="wallmartreq.xml"'#13#10}+aXML.WriteToString +'--qwerty--'#13#10);
Result.Position := 0;
finally
aXML.Free;
end;
end;
function TdmSyncWallmart.CreateHTTP(aContentType: String): TIdHTTP;
begin
Result := TIdHTTP.Create(nil);
Result.ConnectTimeout:=5000;
Result.ReadTimeout:=20000;
Result.ProtocolVersion:=pv1_1;
Result.HTTPOptions := [hoForceEncodeParams, hoKeepOrigProtocol];
Result.HandleRedirects:=True;
Result.IOHandler := SSLHandler;
Result.Request.Accept:='application/xml, */*';
Result.Request.AcceptLanguage:='en-US';
Result.Request.ContentType:=aContentType;
//  Result.Request.CharSet:='utf-8';
Result.Intercept := IdLogEvent1;
end;
procedure TdmSyncWallmart.AddCustomHeaders(aHTTP: TIdHTTP; aSign,
aTimeStamp: String);
begin
aHTTP.Request.CustomHeaders.AddValue('WM_SVC.NAME', 'Walmart Marketplace');
aHTTP.Request.CustomHeaders.AddValue('WM_QOS.CORRELATION_ID', GenGuid);
aHTTP.Request.CustomHeaders.AddValue('WM_SEC.TIMESTAMP', aTimeStamp);
aHTTP.Request.CustomHeaders.AddValue('WM_SEC.AUTH_SIGNATURE', aSign);
aHTTP.Request.CustomHeaders.AddValue('WM_CONSUMER.ID', dstPlatformsUserName.AsString);
aHTTP.Request.CustomHeaders.AddValue('WM_CONSUMER.CHANNEL.TYPE', dstPlatformsPassword.AsString);
end;
//some code for debugging purposes
procedure TdmSyncWallmart.IdLogEvent1Send(ASender: TIdConnectionIntercept;
var ABuffer: TIdBytes);
var
aList: TStringList;
begin
aList := TStringList.Create;
try
aList.Text := BytesToString(ABuffer);
aList.SaveToFile('e:wm_req_txt.txt');
finally
aList.Free;
end;
end;
procedure TdmSyncWallmart.IdLogEvent1Receive(ASender: TIdConnectionIntercept;
var ABuffer: TIdBytes);
var
aList: TStringList;
begin
aList := TStringList.Create;
try
aList.Text := BytesToString(ABuffer);
aList.SaveToFile('e:wm_Resp.txt');
finally
aList.Free;
end;
end;

实际通话

procedure TdmSyncWallmart.SendItems(aIDPlatforms: String; aLastChanged,
aCurrDate: TDateTime);
var
aSign, aTimeStamp: String;
aURL: String;
aHTTP: TIdHTTP;
aRes: String;
aStrm: TMemoryStream;
aReqID: String;
aXML: TNativeXml;
aNode: TXmlNode;
aErrMsg: String;
begin
aURL := dstPlatformsURLAddress.AsString+'/v3/feeds?feedType=item';
GenrateSignature(aSign, aTimeStamp, aURL, 'POST');
if aSign = '' then
Exit;
aHTTP := CreateHTTP('multipart/form-data;boundary=qwerty');
AddCustomHeaders(aHTTP, aSign, aTimeStamp);
try
aStrm := CreateItemFeed(aIDPlatforms, aLastChanged, aCurrDate, aReqID);
if aStrm <> nil then
begin
try
aRes := TIdURI.URLDecode(aHTTP.Post(aURL, aStrm));
aXML := TNativeXml.Create(nil);
try
aXML.ReadFromString(aRes);
aNode := aXML.Root.FindNode('feedId');
cmdUpdFeedID.Parameters.ParamByName('ID').Value := aRes;
cmdUpdFeedID.Parameters.ParamByName('FeedID').Value := aNode.Value;
cmdUpdFeedID.Execute;
finally
aXML.Free;
end;
except
on E:Exception do
begin
if E is EIdHTTPProtocolException then
aErrMsg := E.Message + #13#10 + (E as EIdHTTPProtocolException).ErrorMessage
else
aErrMsg := E.Message;
dmMain.InsLog(cLTError, aErrMsg, aIDPlatforms);
end;
end;
aStrm.Free;
end;
finally
aHTTP.Free;
end;
end;

编辑2

procedure TdmSyncWallmart.SendItems(aIDPlatforms: String; aLastChanged,
aCurrDate: TDateTime);
var
aSign, aTimeStamp: String;
aURL: String;
aHTTP: TIdHTTP;
aRes: String;
aStrm: TMemoryStream;
aReqID: String;
aXML: TNativeXml;
aNode: TXmlNode;
aErrMsg: String;
aIdStream: TIdMultipartFormDataStream;
begin
aURL := dstPlatformsURLAddress.AsString+'/v3/feeds?feedType=item';
GenrateSignature(aSign, aTimeStamp, aURL, 'POST');
if aSign = '' then
Exit;
aHTTP := CreateHTTP('multipart/form-data');
AddCustomHeaders(aHTTP, aSign, aTimeStamp);
try
aStrm := TStringStream.Create();
begin
try
aIdStream := TIdMultiPartFormDataStream.Create;
aIdStream.AddFile('file', 'e:wm_req.xml', 'multipart/form-data');
aIdStream.Position := 0;
astrm.LoadFromStream(aIdStream);
aRes := TIdURI.URLDecode(aHTTP.Post(aURL, aStrm));
aXML := TNativeXml.Create(nil);
try
aXML.ReadFromString(aRes);
aNode := aXML.Root.FindNode('feedId');
cmdUpdFeedID.Parameters.ParamByName('ID').Value := aRes;
cmdUpdFeedID.Parameters.ParamByName('FeedID').Value := aNode.Value;
cmdUpdFeedID.Execute;
finally
aXML.Free;
end;
except
on E:Exception do
begin
if E is EIdHTTPProtocolException then
aErrMsg := E.Message + #13#10 + (E as EIdHTTPProtocolException).ErrorMessage
else
aErrMsg := E.Message;
dmMain.InsLog(cLTError, aErrMsg, aIDPlatforms);
end;
end;
aStrm.Free;
end;
finally
aHTTP.Free;
end;
end;

这是发送的数据

----------060718213723831
Content-Disposition: form-data; name="file"; filename="wm_req.xml"
Content-Type: multipart/form-data
Content-Transfer-Encoding: binary
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<MPItemFeed xmlns:ns2="http://walmart.com/">
<MPItemFeedHeader>
<version>3.1</version>
<requestId>{164726BF-288E-4953-A1DA-1EC7595C5725}</requestId>
<mart>WALMART_US</mart>
</MPItemFeedHeader>
<MPItem>
<processMode>REPLACE_ALL</processMode>
<sku>w-cc-a1-4pk-white-l</sku>
<productIdentifiers>
<productIdentifier>
<productIdType>UPC</productIdType>
<productId>192082276845</productId>
</productIdentifier>
</productIdentifiers>
<MPProduct>
..... the other part of the XML
</MPProduct>
<MPOffer>
<price>25.00</price>
<ShippingWeight>
<measure>11.80</measure>
<unit>lb</unit>
</ShippingWeight>
<ProductTaxCode>2038895</ProductTaxCode>
</MPOffer>
</MPItem>
</MPItemFeed>
----------060718213723831--

拦截部分捕获的返回数据与已经再次使用Cteonnt-Length: 77标头发布的数据相同,但我想如果我成功读取 gzip 数据,我可以到达一个可以转发给支持的错误。

HTTP/1.1 500 Internal Server Error
Method: null
URI: null
WM_CONSUMER.ID: 16248274-1f53-4e6d-880e-b5417698b878
WM_CONSUMER.INTIMESTAMP: 
WM_QOS.CORRELATION_ID: {CB0208AB-2135-4A12-B45F-DD2889273971}
WM_SEC.AUTH_TOKEN: 
WM_SEC.REFRESH_AUTH_TOKEN: 
WM_SVC.CLASS_NAME: com.walmart.services.impl.GMPGatewayService$$EnhancerBySpringCGLIB$$2ca3f3b6
WM_SVC.ENV: prod
WM_SVC.INTIMESTAMP: 1528396669253
WM_SVC.METHOD_NAME: doPostMultiPart
WM_SVC.NAME: Walmart Marketplace
WM_SVC.OUTTIMESTAMP: 1528396669365
WM_SVC.SERVER_IP: 10.65.34.2
WM_SVC.SERVER_NAME: PartnerGMPService-5480119-1-96141274
WM_SVC.VERSION: 
X-Powered-By: soari-interceptors-4.4.4
Content-Type: text/plain
Cteonnt-Length: 77
Server: web
Content-Encoding: gzip
Content-Length: 89
Vary: Accept-Encoding
Expires: Thu, 07 Jun 2018 18:37:49 GMT
Cache-Control: max-age=0, no-cache, no-store
Pragma: no-cache
Date: Thu, 07 Jun 2018 18:37:49 GMT
Connection: close

编辑3

对于我的 Edit1,我根本没有添加内容处置(它被评论) - 有这么多测试,我把它留在了我的帖子中,很抱歉造成混乱。

对于 Edit2 - 感谢您指出这一点,实际上我在没有转换为 TStringStream 的情况下进行了第一次测试,但我想看看它们到底发生了什么。

反正现在我直接用了TIdMultipartFormDataStream,用这种方式修改了代码。

aIdStream := TIdMultiPartFormDataStream.Create;
with aIdStream.AddFile('xml', 'e:wm_req.xml', 'application/xml') do
begin
FileName := '';
//ContentType := '';
FileName := 'wmreq.xml';//somewhere I think I saw that only letters are allowed here
end;
aIdStream.Position := 0;
aStrm := TMemoryStream.Create;
//aRes := TIdURI.URLDecode(aHTTP.Post(aURL, aIdStream));
aHTTP.Post(aURL, aIdStream, aStrm);

感谢雷米,我添加了 TIdCompressorZLib,现在我得到了有意义的错误:

HTTP/1.1 500 内部服务器错误 未找到响应类源确认的消息正文编写器。

我想这是来自他们,而不是来自我,需要与他们核实。

编辑4解决方案

好吧,疯狂与否,也许是我的问题,但是一旦 Remy 说我不是在要求压缩答案并且他们给我发送了这样的答案,我决定将// Result.Request.Accept:='application/xml, */*';更改为仅// Result.Request.Accept:='application/xml';,并且一切都开始正常工作!事实上,拥有*/*意味着我正在接受一切,不是吗?无论您是使用 TIdMultipartFormDataStream 还是手动准备正文,它都可以工作。谢谢雷米的不同观点,另一双眼睛总是有帮助的。疯狂。。。一周的愚蠢测试!

在第一次编辑中,您没有正确填充TStringStream。 请改用这个:

Result.WriteString('--qwerty'#13#10{'Content-Disposition: form-data; name="file"; filename="wallmartreq.xml"'#13#10}#13#10 + aXML.WriteToString + #13#10'--qwerty--'#13#10);

在第二次编辑中,您向TIdMultipartFormDataStream.AddFile()提供了错误的内容类型。 您需要使用application/xml而不是multipart/form-data

aIdStream.AddFile('file', 'e:wm_req.xml', 'application/xml');

或者,将 ContentType 留空(在这种情况下,将改用application/octet-stream):

aIdStream.AddFile('file', 'e:wm_req.xml');

如果根本不想发送内容类型,可以将TIdFormDataField.ContentType属性设置为空字符串:

with aIdStream.AddFile('file', 'e:wm_req.xml') do
begin 
FileName := ''; // needed so ContentType setter will not use a default value...
ContentType := '';
FileName := 'wm_req.xml'; // or whatever you want, or leave blank...
end;

但是,更重要的是,您不再为TIdHTTP.Request.ContentType标头指定boundary属性。 事实上,您根本不应该将TIdMultipartFormDataStream保存到TStringStream然后发布TStringStream。 您应该发布TIdMultipartFormDataStream本身。 这将自动将TIdHTTP.Request.ContentType设置为multipart/form-data,并为其提供正确的boundary属性(其值由TIdMultipartFormDataStream生成):

aHTTP.Post(aURL, aIdStream)

现在,话虽如此,在这两种情况下,您都需要删除对TIdURI.URLDecode()的调用 返回值TIdHTTP.Post(). 服务器应该向您发送原始XML,而不是 URL 编码的 XML,因此您需要按原样处理 XML,而不是对其进行 URL 解码。

此外,由于 XML 在技术上是二进制数据,可以用任何字符集进行编码,这些字符集可能存在也可能不存在,因此您应该让 XML 解析器完全按照服务器发送的方式处理 XML。 为此,请使用填充TStream而不是返回String的重载版本的TIdHTTP.Post()。 让它将服务器的XML接收到TMemoryStream中,然后将该流加载到解析器中(TNativeXml有一个LoadFromStream()方法)。


最后,您显示服务器的响应具有Content-Encoding: gzip响应标头,但我没有看到您将任何对象分配给TIdHTTP.Compressor属性,或手动设置TIdHTTP.Request.AcceptEncoding属性,因此服务器不应以压缩格式发送响应正文,因为您没有要求该格式。TIdHTTP不会在未分配Compressor的情况下自动解压缩数据。

如果服务器确实在没有被询问的情况下发送压缩数据,那就是服务器端的错误,您应该向沃尔玛报告。

相关内容

  • 没有找到相关文章

最新更新