使用npm request向SOAP api发送请求

7

我想要达到这个目标:

POST /oms/order.asmx HTTP/1.1  
Host:myserver.com 
Content-Type: text/xml; 
charset=utf-8 
Content-Length: length  
SOAPAction: "http://shipping_software/AddOrder"

通过这样做:
var newOrder = buildOrder(orderInfo);
var soapOptions = {
    uri: '/oms/order.asmx',
    headers: {
        'Content-Type': 'text/xml',
        'charset': 'utf-8',
        'Content-Length': newOrder.length.toString(),
        'SOAPAction': 'http://shipping_software/AddOrder',
        'Host': 'myserver.com',
        'Connection': 'keep-alive'
    },
    method: 'POST',
    body: newOrder //New order is properly formed xml as a String
}
request(soapOptions, function(err, response) {
        console.log(err);
        console.log(response);
    })
    // console.log(newOrder);
});

当前返回“无效的URI”,当我将URI更改为http://myserver.com/oms/order.asmx时,仍然会收到400响应代码。

编辑:我修复了内容类型以使其成为一行Content-Type: text/html; charset=utf-8,但没有任何改进。

编辑2:我正在使用XMLBuilder构建我的XML数据,并尝试在不将其转换为字符串的情况下提交它,但是与SOAP API的连接超时。

编辑3:完整的SOAP请求:

POST /oms/order.asmx HTTP/1.1
Host: myserver.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://oms/AddOrder"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <AuthenticationHeader xmlns="http://sma-promail/">
      <Username>string</Username>
      <Password>string</Password>
    </AuthenticationHeader>
    <DebugHeader xmlns="http://sma-promail/">
      <Debug>boolean</Debug>
      <Request>string</Request>
    </DebugHeader>
  </soap:Header>
  <soap:Body>
    <AddOrder xmlns="http://sma-promail/">
      <order>
        <Header>
          <ID>string</ID>
          <EntryDate>dateTime</EntryDate>
          <OrderEntryView>
            <SeqID>int</SeqID>
            <Description>string</Description>
          </OrderEntryView>
          <ReferenceNumber>string</ReferenceNumber>
          <PONumber>string</PONumber>
          <Comments>string</Comments>
          <IpAddress>string</IpAddress>
          <ApprovalComment>string</ApprovalComment>
          <InsertDate>dateTime</InsertDate>
        </Header>
        <Classification>
          <CampaignID>string</CampaignID>
          <ResponseMedia>
            <Description>string</Description>
          </ResponseMedia>
          <Source>
            <Description>string</Description>
          </Source>
          <Issue>
            <Issue>string</Issue>
          </Issue>
          <CustomerProject>
            <ID>string</ID>
          </CustomerProject>
          <CustomerCode>string</CustomerCode>
          <Store>string</Store>
          <Department>string</Department>
          <DistributionCenter>string</DistributionCenter>
          <Vendor>string</Vendor>
        </Classification>
        <Shipping>
          <FreightCarrier>
            <Name>string</Name>
          </FreightCarrier>
          <FreightService>
            <Description>string</Description>
          </FreightService>
          <FreightAccount>
            <SeqID>int</SeqID>
            <Description>string</Description>
            <FreightCarrier xsi:nil="true" />
            <Person xsi:nil="true" />
            <ThirdAcctNo>string</ThirdAcctNo>
            <NonResident>boolean</NonResident>
          </FreightAccount>
          <ShippingOption>
            <Description>string</Description>
          </ShippingOption>
          <FreightCode>string</FreightCode>
          <FreightCodeDescription>string</FreightCodeDescription>
          <ShipComments>string</ShipComments>
          <NeededBy>string</NeededBy>
          <Rush>boolean</Rush>
          <ReleaseDate>dateTime</ReleaseDate>
          <ThirdPartyType>int</ThirdPartyType>
          <ThirdAccountNumber>string</ThirdAccountNumber>
          <NCShip>boolean</NCShip>
          <NCPack>boolean</NCPack>
          <NCOffers>boolean</NCOffers>
          <NCHandling>boolean</NCHandling>
          <NCOffShipHandling>boolean</NCOffShipHandling>
          <NCSpecialHandling>boolean</NCSpecialHandling>
          <NCRush>boolean</NCRush>
        </Shipping>
        <Money>
          <PriceClass>
            <SeqID>int</SeqID>
            <Description>string</Description>
          </PriceClass>
          <ShippingHandlingCharge>decimal</ShippingHandlingCharge>
          <RushHandlingCharge>decimal</RushHandlingCharge>
          <NoChargeType>
            <Description>string</Description>
          </NoChargeType>
          <DiscountAmount>decimal</DiscountAmount>
          <DiscountPercent>float</DiscountPercent>
          <DiscountCode>
            <ID>string</ID>
            <Description>string</Description>
          </DiscountCode>
          <Coupon>
            <Code>string</Code>
          </Coupon>
          <SpecialHandlingCharge>decimal</SpecialHandlingCharge>
          <CreditAmount>decimal</CreditAmount>
          <GiftCertificate>
            <UID>string</UID>
            <Amount>decimal</Amount>
          </GiftCertificate>
          <GiftCertificateAmount>decimal</GiftCertificateAmount>
          <TaxPercent>decimal</TaxPercent>
          <NoChargeAmount>decimal</NoChargeAmount>
          <TaxAmount>decimal</TaxAmount>
        </Money>
        <Payment>
          <PaymentType>
            <Description>string</Description>
            <Sequence>int</Sequence>
          </PaymentType>
          <PaymentAmount>decimal</PaymentAmount>
          <CCNumber>string</CCNumber>
          <CCExpirationDate>string</CCExpirationDate>
          <CSC>string</CSC>
          <ARReference>string</ARReference>
        </Payment>
        <OrderVariables>
          <OrderVariable>
            <SeqID>int</SeqID>
            <VariableField xsi:nil="true" />
            <Value>string</Value>
          </OrderVariable>
          <OrderVariable>
            <SeqID>int</SeqID>
            <VariableField xsi:nil="true" />
            <Value>string</Value>
          </OrderVariable>
        </OrderVariables>
        <OrderedBy>
          <ORDOBY>
            <SeqID>int</SeqID>
            <CustomerID>string</CustomerID>
          </ORDOBY>
          <FullName>string</FullName>
          <FullNameWithSuffix>string</FullNameWithSuffix>
          <CityStateZip>string</CityStateZip>
          <CityStateZipCountry>string</CityStateZipCountry>
          <CompoundAddress>string</CompoundAddress>
        </OrderedBy>
        <ShipTo>
          <OrderShipTo>
            <SeqID>int</SeqID>
            <Flag>Other or OrderedBy</Flag>
            <Key>string</Key>
            <NeededBy>string</NeededBy>
            <ReleaseDate>dateTime</ReleaseDate>
            <Rush>boolean</Rush>
            <RushHandling>decimal</RushHandling>
            <Comments>string</Comments>
            <FreightCarrier xsi:nil="true" />
            <FreightService xsi:nil="true" />
            <ThirdPartyType>int</ThirdPartyType>
            <ThirdPartyAccountNumber>string</ThirdPartyAccountNumber>
            <FreightCode>string</FreightCode>
            <FreightCodeDescription>string</FreightCodeDescription>
            <SpecialHandling xsi:nil="true" />
            <SpecialHandlingCharge>decimal</SpecialHandlingCharge>
            <ShippingHandlingCharge>decimal</ShippingHandlingCharge>
            <FullName>string</FullName>
            <FullNameWithSuffix>string</FullNameWithSuffix>
            <CityStateZip>string</CityStateZip>
            <CityStateZipCountry>string</CityStateZipCountry>
            <CompoundAddress>string</CompoundAddress>
            <PickPacks xsi:nil="true" />
          </OrderShipTo>
          <OrderShipTo>
            <SeqID>int</SeqID>
            <Flag>Other or OrderedBy</Flag>
            <Key>string</Key>
            <NeededBy>string</NeededBy>
            <ReleaseDate>dateTime</ReleaseDate>
            <Rush>boolean</Rush>
            <RushHandling>decimal</RushHandling>
            <Comments>string</Comments>
            <FreightCarrier xsi:nil="true" />
            <FreightService xsi:nil="true" />
            <ThirdPartyType>int</ThirdPartyType>
            <ThirdPartyAccountNumber>string</ThirdPartyAccountNumber>
            <FreightCode>string</FreightCode>
            <FreightCodeDescription>string</FreightCodeDescription>
            <SpecialHandling xsi:nil="true" />
            <SpecialHandlingCharge>decimal</SpecialHandlingCharge>
            <ShippingHandlingCharge>decimal</ShippingHandlingCharge>
            <FullName>string</FullName>
            <FullNameWithSuffix>string</FullNameWithSuffix>
            <CityStateZip>string</CityStateZip>
            <CityStateZipCountry>string</CityStateZipCountry>
            <CompoundAddress>string</CompoundAddress>
            <PickPacks xsi:nil="true" />
          </OrderShipTo>
        </ShipTo>
        <BillTo>
          <Flag>Other or OrderedBy or DoNotUse or ShipTo</Flag>
          <FullName>string</FullName>
          <FullNameWithSuffix>string</FullNameWithSuffix>
          <CityStateZip>string</CityStateZip>
          <CityStateZipCountry>string</CityStateZipCountry>
          <CompoundAddress>string</CompoundAddress>
        </BillTo>
        <Offers>
          <OfferOrdered>
            <Offer xsi:nil="true" />
            <Quantity>int</Quantity>
            <CanceledQuantity>int</CanceledQuantity>
            <OrderShipTo xsi:nil="true" />
            <OrderShipToKey xsi:nil="true" />
            <PriceType>unsignedByte</PriceType>
            <UnitPrice>decimal</UnitPrice>
            <ShipType>short</ShipType>
            <ShippingHandling>decimal</ShippingHandling>
            <Discounts>decimal</Discounts>
            <DiscountPercent>int</DiscountPercent>
            <DocumentID>string</DocumentID>
            <SeqID>int</SeqID>
            <CloneLine>int</CloneLine>
            <Unapproved>boolean</Unapproved>
            <ShipToKey>string</ShipToKey>
            <FgnOrder>string</FgnOrder>
            <Comments>string</Comments>
            <RCOrderKey>string</RCOrderKey>
            <Recurring>boolean</Recurring>
            <LineNumber>int</LineNumber>
            <Variables xsi:nil="true" />
            <ProductDetails xsi:nil="true" />
          </OfferOrdered>
          <OfferOrdered>
            <Offer xsi:nil="true" />
            <Quantity>int</Quantity>
            <CanceledQuantity>int</CanceledQuantity>
            <OrderShipTo xsi:nil="true" />
            <OrderShipToKey xsi:nil="true" />
            <PriceType>unsignedByte</PriceType>
            <UnitPrice>decimal</UnitPrice>
            <ShipType>short</ShipType>
            <ShippingHandling>decimal</ShippingHandling>
            <Discounts>decimal</Discounts>
            <DiscountPercent>int</DiscountPercent>
            <DocumentID>string</DocumentID>
            <SeqID>int</SeqID>
            <CloneLine>int</CloneLine>
            <Unapproved>boolean</Unapproved>
            <ShipToKey>string</ShipToKey>
            <FgnOrder>string</FgnOrder>
            <Comments>string</Comments>
            <RCOrderKey>string</RCOrderKey>
            <Recurring>boolean</Recurring>
            <LineNumber>int</LineNumber>
            <Variables xsi:nil="true" />
            <ProductDetails xsi:nil="true" />
          </OfferOrdered>
        </Offers>
        <OrderRecurrenceSchedule>
          <RecurrenceSchedules>
            <SeqID>int</SeqID>
            <ID>string</ID>
            <Description>string</Description>
            <Definition>string</Definition>
            <DefinitionDetail>string</DefinitionDetail>
            <Schedule>EveryXDays or EveryXWeeks or EveryXMonths</Schedule>
            <ScheduleCount>int</ScheduleCount>
            <Cycle>Rolling or Custom</Cycle>
            <StartCycleDate>dateTime</StartCycleDate>
            <DaysToJoin>int</DaysToJoin>
            <MonthlyRecurrenceType>DayOfMonth or WeekOfMonthAndDayOfWeek</MonthlyRecurrenceType>
            <MinimumRecurrences>int</MinimumRecurrences>
            <MaximumRecurrences>int</MaximumRecurrences>
            <RecurrenceIncrement>int</RecurrenceIncrement>
            <AllowInfiniteRecurrence>boolean</AllowInfiniteRecurrence>
            <InfiniteTag>string</InfiniteTag>
            <DurationTag>string</DurationTag>
            <ExpirationDate>dateTime</ExpirationDate>
            <NextCycleDate>dateTime</NextCycleDate>
            <HasValidCycleDate>boolean</HasValidCycleDate>
            <AnyOffer>boolean</AnyOffer>
            <RecurrenceScheduleShippingOptions xsi:nil="true" />
          </RecurrenceSchedules>
          <RecurrenceOfferFlag>boolean</RecurrenceOfferFlag>
          <RecurrenceShippingOption>
            <Description>string</Description>
          </RecurrenceShippingOption>
          <RecurrenceSpecialHandlingCharge>decimal</RecurrenceSpecialHandlingCharge>
          <NumberRecurrence>int</NumberRecurrence>
        </OrderRecurrenceSchedule>
        <OrderBudget>
          <Person>
            <Name xsi:nil="true" />
            <CompanyInfo xsi:nil="true" />
            <Address xsi:nil="true" />
            <ContactInfo xsi:nil="true" />
            <BillingInfo xsi:nil="true" />
            <Variables xsi:nil="true" />
          </Person>
        </OrderBudget>
      </order>
    </AddOrder>
  </soap:Body>
</soap:Envelope>
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <DebugHeader xmlns="http://sma-promail/">
      <Debug>boolean</Debug>
      <Request>string</Request>
    </DebugHeader>
  </soap:Header>
  <soap:Body>
    <AddOrderResponse xmlns="http://sma-promail/">
      <AddOrderResult>
        <OrderSeqID>int</OrderSeqID>
        <OrderID>string</OrderID>
      </AddOrderResult>
    </AddOrderResponse>
  </soap:Body>
</soap:Envelope>

头部似乎已经正确设置:_header: 'POST /oms/order.asmx HTTP/1.1\r\nContent-Type: text/xml\r\ncharset: utf-8\r\nContent-Length: 1161\r\nSOAPAction: http://oms/AddOrder\r\nHost: myserver.com\r\nConnection: keep-alive\r\n\r\n' - goofiw
说实话,如果没有看到完整的HTTP请求,就很难弄清楚为什么你的服务器会返回400错误。 - brandonscript
1
这与问题并不直接相关,但您是否考虑过使用像soap这样的模块,它可以使与SOAP端点的工作更加容易? - mscdex
@mscdex,很抱歉我找不到许可证。 - goofiw
啊,项目根目录中所有字母都大写的文件。 - goofiw
显示剩余4条评论
2个回答

2

虽然略微偏离了文章标题,但我最终选择使用Node.js进行HTTP开发。

var newOrder = "<?xml version='1.0' encoding='utf-8'?><soap:Envelope><soap:Header>.....</soap:Envelope>"

    var postOptions = {
      hostname: 'server.com',
      port: 80,
      path: '/oms/order.asmx?wsdl',
      method: 'POST',
      headers: {
        'Host':'server.com',
        'Content-Type':'text/xml;charset=utf-8',
        'Content-Length':newOrder.length,
        'SOAPAction':"http://sma-promail/AddOrder", 
      }
    };

    var req = http.request(postOptions, function(res) {
      console.log('STATUS: ' + res.statusCode);
      console.log('HEADERS: ' + JSON.stringify(res.headers));
      res.setEncoding('utf8');
      res.on('data', function (chunk) {
        console.log('BODY: ' + chunk);
      });
    });

    req.on('error', function(e) {
      console.log('problem with request: ' + e.message);
    });

    // write data to request body
    req.write(newOrder);
    req.end();
  });

2

到目前为止只是猜测,但假设所有的头文件都已经正确设置,那么唯一引人注目的是content-type头文件——你将类型和字符集分成了多个键值对;它应该在单独的一行上:

var newOrder = buildOrder(orderInfo);
var soapOptions = {
    uri: 'http://myserver.com/oms/order.asmx',
    headers: {
        'Content-Type': 'text/xml; charset=utf-8',
        'Content-Length': newOrder.length.toString(),
        'SOAPAction': 'http://shipping_software/AddOrder',
        'Host': 'myserver.com',
        'Connection': 'keep-alive'
    },
    method: 'POST',
    body: newOrder //New order is properly formed xml as a String
}
request(soapOptions, function(err, response) {
        console.log(err);
        console.log(response);
    })
    // console.log(newOrder);
});

此外,正如您在问题中指出的那样,请确保uri是一个完全合格的URL,而不仅仅是路径后缀。


好的 - 试着用curl让它工作。如果可以的话,请将该命令添加到您的问题中。 - brandonscript
我一直在尝试使curl soap调用工作,但是没有返回任何内容:curl -H 'Content-Type: text/xml; charset=utf-8' -H 'Content-Length: 1150' -H 'SOAPAction:http://sma-promail/AddOrder' --data @sampleOrder.txt http://myserver.com/pmomsws/order.asmx?wsdl - goofiw
嗯,好的,如果你无法让它工作,那肯定是问题所在。我建议你找一些关于你的服务器的文档或者找一个可用的请求示例。 - brandonscript
我可能在我的XML字符串中漏掉了什么吗?我认为它仍然会建立连接并响应一个错误,说明我漏掉了某些内容。 - goofiw
不知道你的服务器在做什么或者它期望什么,就像在一片干草堆中寻找针一样困难 :( - brandonscript
我有那些文档,但它们似乎没有很好地组合在一起(存在一些不一致之处)。http://pmdev.gloful.com/pmomsws/order.asmx?op=AddOrder - goofiw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接