使用Node.js strong-soap调用Bing Ads API遇ECONNRESET错误求助
问题:strong-soap调用必应广告GetUser接口触发ECONNRESET错误
我用strong-soap调用必应广告的GetUser接口,客户端能正常创建,但调用client.GetUser()时直接抛出ECONNRESET错误。如果删掉AuthenticationToken和DeveloperToken这两个SOAP头,连接不会断,会返回「Authentication failed. Either supplied credentials are invalid or the account is inactive」的提示。
当前代码
const wsdlURI = "https://clientcenter.api.bingads.microsoft.com/Api/CustomerManagement/v13/CustomerManagementService.svc?singleWsdl"; const options = { envelopeKey: 's', }; soap.createClient(wsdlURI, { ...options }, (err: any, client: any) => { if (err) { throw err } client.addSoapHeader(`<h:AuthenticationToken i:nil="false">${access_token}</h:AuthenticationToken>`) client.addSoapHeader(`<h:DeveloperToken i:nil="false">${process.env.MICROSOFT_ADS_DEVELOPER_TOKEN}</h:DeveloperToken>`) client.GetUser(null, (err: any, res: any, env: any, soapHeader: any) => { if (err) { throw err } console.log("Res:", res) console.log("Env:", env) }, null) })
错误信息
Error: read ECONNRESET at TLSWrap.onStreamRead (node:internal/stream_base_commons:217:20) at TLSWrap.callbackTrampoline (node:internal/async_hooks:130:17) { errno: -54, code: 'ECONNRESET', syscall: 'read' }
生成的请求XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header> <h:AuthenticationToken i:nil="false">...</h:AuthenticationToken> <h:DeveloperToken i:nil="false">...</h:DeveloperToken> </s:Header> <s:Body/> </s:Envelope>
解决思路&方案
看生成的XML就能发现问题:h:前缀没有定义对应的命名空间,必应广告API的SOAP头要求必须指定https://bingads.microsoft.com/Customer/v13这个命名空间,缺失的话服务器解析不了请求,直接断开连接,就出现了ECONNRESET。
1. 给SOAP头补全命名空间
别分开加两个头,直接拼完整的带命名空间的XML头部:
const fullSoapHeader = ` <soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:h="https://bingads.microsoft.com/Customer/v13" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <h:AuthenticationToken i:nil="false">${access_token}</h:AuthenticationToken> <h:DeveloperToken i:nil="false">${process.env.MICROSOFT_ADS_DEVELOPER_TOKEN}</h:DeveloperToken> </soapenv:Header> `; // 替换原来的两次addSoapHeader调用 client.addSoapHeader(fullSoapHeader);
2. 用对象式添加头部(更稳妥,避免XML拼接错误)
strong-soap支持用对象结构传头部,会自动处理命名空间:
const soapHeaders = { 'h:AuthenticationToken': access_token, 'h:DeveloperToken': process.env.MICROSOFT_ADS_DEVELOPER_TOKEN, attributes: { 'xmlns:h': 'https://bingads.microsoft.com/Customer/v13', 'xmlns:i': 'http://www.w3.org/2001/XMLSchema-instance' } }; client.addSoapHeader(soapHeaders);
3. 尝试给GetUser传合法参数
虽然GetUser允许空Body,但有些SOAP服务对空Body的处理有问题,可以试试传个符合定义的参数:
// 传入UserId参数,null表示获取当前用户 client.GetUser({ UserId: null }, (err: any, res: any) => { if (err) { console.error(err); return; } console.log("Res:", res); });
4. 排查网络问题
如果上面的方法都没用,检查下是不是代理、防火墙拦截了请求,或者Node.js版本太老导致TLS兼容性问题,升级到最新稳定版试试。
内容的提问来源于stack exchange,提问作者Ethan Crabb
相关产品推荐
相关产品推荐

