You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中用soap npm调用SOAP API遇信封转换失败问题求助

解决Node.js soap包调用Sabre SSSAdvShopRQ接口缺少Header的问题

调用Sabre的SSSAdvShopRQ接口时,使用Node.js的soap npm包构建参数对象后,无法转换为正确的SOAP请求信封,返回错误:

soap-env:Fault soap-env:Client.InvalidEbXmlMessage Missing <soap-env:Header> in <soap-env:Envelope> javax.xml.soap.SOAPException: Missing <soap-env:Header> in <soap-env:Envelope>

原app.js代码

var soap = require('soap');
const express = require('express');
const bodyParser = require('body-parser');

var app = express();
app.use(bodyParser.json());
const url = 'https://files.developer.sabre.com/wsdl/sabreXML1.0.00/shopping/SSSAdvShopRQ_v5-4-0.wsdl';

let params = {
    Envelope: {
        Header: {
            Action:"SSSAdvShopRQ",
            Security: {
                BinarySecurityToken: "Token"
            },
            MessageHeader: {
                From: {
                    PartyId:[ "WebServiceClient"]
                },
                To: {
                    PartyId:[ "WebServiceSupplier"]
                },
                CPAId: "ET",
                ConversationId: "TestSession",
                Service: "SSSAdvShop",
                Action: "SSSAdvShopRQ"
            },
        },
        Body: {
            OTA_AirLowFareSearchRQ: {
                POS: {
                    Source: {
                        RequestorID: {
                            CompanyName: {
                            Code: "SSW"
                            },
                        Type: "1",
                        ID: "1"
                        },
                    PseudoCityCode: "ADD"
                    }
                },
                OriginDestinationInformation: [
                    {
                        DepartureDateTime: "2023-01-25T00:00:00",
                        OriginLocation: {
                        LocationCode: "ADD"
                        },
                        DestinationLocation: {
                        LocationCode: "DXB"
                        },
                        TPA_Extensions: "",
                    RPH: "1"
                    },
                    {
                        DepartureDateTime: "2023-01-31T00:00:00",
                        OriginLocation: {
                        LocationCode: "DXB"
                        },
                        DestinationLocation: {
                        LocationCode: "SEA"
                        },
                        TPA_Extensions: "",
                    RPH: "2"
                    }
                ],
                TravelPreferences: "",
                TravelerInfoSummary: {
                    AirTravelerAvail: {
                        PassengerTypeQuantity: {
                        Code: "ADT",
                        Quantity: "1"
                        }
                    },
                    PriceRequestInformation: {
                        TPA_Extensions: {
                            Indicators: {
                                RetainFare: {
                                Ind: "true"
                                },
                                MinMaxStay: {
                                Ind: "true"
                                },
                                RefundPenalty: {
                                Ind: "true"
                                },
                                ResTicketing: {
                                Ind: "true"
                                },
                                TravelPolicy: {
                                Ind: "true"
                                }
                            },
                            PointOfSaleOverride: {
                            Code: "ADD"
                            }
                        },
                    CurrencyCode: "ETB"
                    }
                },
                TPA_Extensions: {
                    IntelliSellTransaction: {
                        RequestType: {
                        Name: "ADVBRD"
                        },
                        ServiceTag: {
                        Name: "ET"
                        }
                    }
                },
            Version: "5.4.0"
                        },
        }
    }
};

app.get('/', function (req, res) {
    soap.createClient(url, function (err, client) {
        client.SSSAdvShopRQAsync(params, function (err, response) {
        console.log(response.data);
        res.setHeader('Content-Type', 'application/json');
        res.status(200).send(response.data);
        });
    });
});

app.listen(3000, () => {
    console.log("Server started at port 3000");
});

错误响应

soap-env:Fault
soap-env:Client.InvalidEbXmlMessage
Missing soap-env:Header in soap-env:Envelope

javax.xml.soap.SOAPException: Missing soap-env:Header in soap-env:Envelope

</soap-env:Fault>

解决方法

问题出在soap包的用法错误:soap包会自动生成SOAP Envelope结构,不需要手动传入整个Envelope对象,否则包无法正确识别Header部分。正确做法是拆分Header和业务参数,单独设置Header,只将业务数据作为接口参数传入。

修改后的代码

var soap = require('soap');
const express = require('express');
const bodyParser = require('body-parser');

var app = express();
app.use(bodyParser.json());
const url = 'https://files.developer.sabre.com/wsdl/sabreXML1.0.00/shopping/SSSAdvShopRQ_v5-4-0.wsdl';

// 单独提取Header内容
const soapHeader = {
    Action:"SSSAdvShopRQ",
    Security: {
        BinarySecurityToken: "Token"
    },
    MessageHeader: {
        From: {
            PartyId:[ "WebServiceClient"]
        },
        To: {
            PartyId:[ "WebServiceSupplier"]
        },
        CPAId: "ET",
        ConversationId: "TestSession",
        Service: "SSSAdvShop",
        Action: "SSSAdvShopRQ"
    },
};

// 业务参数只保留Body中的OTA_AirLowFareSearchRQ内容
let params = {
    OTA_AirLowFareSearchRQ: {
        POS: {
            Source: {
                RequestorID: {
                    CompanyName: {
                    Code: "SSW"
                    },
                Type: "1",
                ID: "1"
                },
            PseudoCityCode: "ADD"
            }
        },
        OriginDestinationInformation: [
            {
                DepartureDateTime: "2023-01-25T00:00:00",
                OriginLocation: {
                LocationCode: "ADD"
                },
                DestinationLocation: {
                LocationCode: "DXB"
                },
                TPA_Extensions: "",
            RPH: "1"
            },
            {
                DepartureDateTime: "2023-01-31T00:00:00",
                OriginLocation: {
                LocationCode: "DXB"
                },
                DestinationLocation: {
                LocationCode: "SEA"
                },
                TPA_Extensions: "",
            RPH: "2"
            }
        ],
        TravelPreferences: "",
        TravelerInfoSummary: {
            AirTravelerAvail: {
                PassengerTypeQuantity: {
                Code: "ADT",
                Quantity: "1"
                }
            },
            PriceRequestInformation: {
                TPA_Extensions: {
                    Indicators: {
                        RetainFare: {
                        Ind: "true"
                        },
                        MinMaxStay: {
                        Ind: "true"
                        },
                        RefundPenalty: {
                        Ind: "true"
                        },
                        ResTicketing: {
                        Ind: "true"
                        },
                        TravelPolicy: {
                        Ind: "true"
                        }
                    },
                    PointOfSaleOverride: {
                    Code: "ADD"
                    }
                },
            CurrencyCode: "ETB"
            }
        },
        TPA_Extensions: {
            IntelliSellTransaction: {
                RequestType: {
                Name: "ADVBRD"
                },
                ServiceTag: {
                Name: "ET"
                }
            }
        },
    Version: "5.4.0"
    }
};

app.get('/', function (req, res) {
    soap.createClient(url, function (err, client) {
        // 添加SOAP Header
        client.addSoapHeader(soapHeader);
        // 只传入业务参数
        client.SSSAdvShopRQAsync(params, function (err, response) {
            if (err) {
                console.error(err);
                res.status(500).send(err);
                return;
            }
            console.log(response.data);
            res.setHeader('Content-Type', 'application/json');
            res.status(200).send(response.data);
        });
    });
});

app.listen(3000, () => {
    console.log("Server started at port 3000");
});

关键改动说明

  • 将Header内容从params中拆分出来,通过client.addSoapHeader()方法单独设置,确保soap包正确将其放入SOAP Envelope的Header部分。
  • params只保留业务请求体(OTA_AirLowFareSearchRQ),这是SSSAdvShopRQAsync方法需要的参数,soap包会自动将其包裹到Envelope的Body中。
  • 添加了错误处理,方便排查调用中的其他问题。

内容的提问来源于stack exchange,提问作者Samuel Wakuma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 21:15:36