【问题标题】:Simplest SOAP example最简单的 SOAP 示例
【发布时间】:2008-09-23 22:17:03
【问题描述】:

使用 Javascript 的最简单的 SOAP 示例是什么?

为了尽可能有用,答案应该:

  • 功能正常(换句话说,实际工作)
  • 至少发送一个可以在代码其他地方设置的参数
  • 处理至少一个可以在代码中其他地方读取的结果值
  • 使用大多数现代浏览器版本
  • 尽可能简洁明了,不使用外部库

【问题讨论】:

  • 简单明了可能与不使用外部库发生冲突。你真的要编写自己的 WSDL -> JS 类转换器吗?
  • 我有一个问题:如果我第一个看到这个问题,我希望它会被 cmets 否决,例如“显示一些代码,这不是'租用编码器'”。没什么私人的,Thomas :) 但我无法理解社区如何决定好与坏。
  • 嘿,不用担心。我想问题的重点是有很多方法可以使用 JavaScript 编写 SOAP 客户端。他们中的许多人都很丑,所以我希望有一些保持清洁的想法。
  • @dan 这是因为 1. 这个问题相当老了,仍然有很多基本问题被问到,传统上有很多赞成票,2. 它描述了一个相当简单的问题,所以它可能倾向于以“嘿,我也想知道!”的原则吸引可能投票的新用户而不是“嘿,这个问题显示了研究工作。它有用且清晰!”。由于我认为这个问题缺乏这个,我投了反对票。也没有什么私人的:D
  • @ThomasBratt 我可能会在元数据上继续这个问题,但这类问题值得一个机会。这是参考或知识库的下降图书馆的理想问题。但也许接受的答案也值得额外跑腿的激励?仍然没有什么比 SO 更被接受的了,那么还有什么地方呢?甚至 SO 也尝试过构建文档站点的想法,但失败了。没有什么可以取代 SO ...

标签: javascript soap


【解决方案1】:

这是我可以创建的最简单的 JavaScript SOAP 客户端。

<html>
<head>
    <title>SOAP JavaScript Client Test</title>
    <script type="text/javascript">
        function soap() {
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open('POST', 'https://somesoapurl.com/', true);

            // build SOAP request
            var sr =
                '<?xml version="1.0" encoding="utf-8"?>' +
                '<soapenv:Envelope ' + 
                    'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
                    'xmlns:api="http://127.0.0.1/Integrics/Enswitch/API" ' +
                    'xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' +
                    'xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">' +
                    '<soapenv:Body>' +
                        '<api:some_api_call soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' +
                            '<username xsi:type="xsd:string">login_username</username>' +
                            '<password xsi:type="xsd:string">password</password>' +
                        '</api:some_api_call>' +
                    '</soapenv:Body>' +
                '</soapenv:Envelope>';

            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 4) {
                    if (xmlhttp.status == 200) {
                        alert(xmlhttp.responseText);
                        // alert('done. use firebug/console to see network response');
                    }
                }
            }
            // Send the POST request
            xmlhttp.setRequestHeader('Content-Type', 'text/xml');
            xmlhttp.send(sr);
            // send request
            // ...
        }
    </script>
</head>
<body>
    <form name="Demo" action="" method="post">
        <div>
            <input type="button" value="Soap" onclick="soap();" />
        </div>
    </form>
</body>
</html> <!-- typo -->

【讨论】:

  • 发送
    怎么样?我尝试将我的标头标签构建到 sr 变量中,但是服务器收到一个空的 soapenv:Header
  • 这对我有用! (在用真实的 URL 替换 SOAP 服务 URL 并关闭我的浏览器上的跨域限制后,@Prestaul 暗示)
  • 我正在为 android/ios 使用 nativescript 开发跨平台应用程序。我想使用 SOAP Web 服务。请指导我。我将上面的代码用于 SOAP 请求 & 我想要 SOAP 响应格式,如何处理响应。请查看我的问题 - stackoverflow.com/questions/37745840/…
  • 最近不得不使用它来支持遗留代码。遇到一个缺少标头的问题,该问题导致“EndpointDispatcher 的 ContractFilter 不匹配”。在xmlhttp.send(sr) 之前添加xmlhttp.setRequestHeader('SOAPAction', 'http://myurl.com/action'); 修复它。
  • @Rickchip,here 是解决您问题的更通用方法:可以在需要时通过调用 setRequestHeader() 添加标题。
【解决方案2】:

浏览器处理 XMLHttpRequest 的方式有很多怪癖,这个 JS 代码将适用于所有浏览器:
https://github.com/ilinsky/xmlhttprequest

此 JS 代码将 XML 转换为易于使用的 JavaScript 对象:
http://www.terracoder.com/index.php/xml-objectifier

上面的JS代码可以包含在页面中,以满足您无外部库的要求。

var symbol = "MSFT"; 
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "http://www.webservicex.net/stockquote.asmx?op=GetQuote",true);
xmlhttp.onreadystatechange=function() {
 if (xmlhttp.readyState == 4) {
  alert(xmlhttp.responseText);
  // http://www.terracoder.com convert XML to JSON 
  var json = XMLObjectifier.xmlToJSON(xmlhttp.responseXML);
  var result = json.Body[0].GetQuoteResponse[0].GetQuoteResult[0].Text;
  // Result text is escaped XML string, convert string to XML object then convert to JSON object
  json = XMLObjectifier.xmlToJSON(XMLObjectifier.textToXML(result));
  alert(symbol + ' Stock Quote: $' + json.Stock[0].Last[0].Text); 
 }
}
xmlhttp.setRequestHeader("SOAPAction", "http://www.webserviceX.NET/GetQuote");
xmlhttp.setRequestHeader("Content-Type", "text/xml");
var xml = '<?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:Body> ' +
     '<GetQuote xmlns="http://www.webserviceX.NET/"> ' +
       '<symbol>' + symbol + '</symbol> ' +
     '</GetQuote> ' +
   '</soap:Body> ' +
 '</soap:Envelope>';
xmlhttp.send(xml);
// ...Include Google and Terracoder JS code here...

另外两个选项:

【讨论】:

  • 如果我想传递多个信封怎么办?
  • 我正在使用上面的代码,但是 xmlhttp.responseText 总是结果为 null。你能给我一些链接来克服这个错误
  • 删除 Google 代码时的链接:github.com/ilinsky/xmlhttprequest
【解决方案3】:

这不能用直接的 JavaScript 完成,除非 Web 服务与您的页面在同一个域中。 编辑:在 2008 年和 IE

如果 Web 服务在另一个域中[并且您必须支持 IE

如果 Web 服务在您自己的域中,则不要使用 SOAP。没有充分的理由这样做。如果 Web 服务在您自己的域中,则对其进行修改,以便它可以返回 JSON,并省去处理 SOAP 带来的所有麻烦。

简短的回答是:不要从 javascript 发出 SOAP 请求。使用 Web 服务从另一个域请求数据,如果这样做,则在服务器端解析结果并以 js 友好的形式返回。

【讨论】:

  • 目的是让 SOAP 服务器也为简单的测试和评估提供 HTML 页面。客户端将在同一个域上。不使用 SOAP 作为前端似乎是公认的观点。关于为什么?请添加到新问题:stackoverflow.com/questions/127038
  • 在那里回答毫无意义...我在所有三点上都同意 Gizmo。 XML 是臃肿的,用 js 处理是一个挑战,而 JSON 是简洁和原生的。
  • re “无法完成”:如果客户端支持Cross-Origin Resource Sharing,今天它可以(大部分)直接使用 JavaScript 完成。希望在 3 到 4 年内它会普遍可用。
  • @Constantin,如果您愿意只支持较新的浏览器并且您可以控制服务器并且也可以在那里添加 CORS 支持,那么 CORS 将允许它。话虽如此,我仍然认为 SOAP 调用应该只在服务器之间进行,而客户端应该使用对 JS 更友好的东西,比如 JSON。
  • -1 因为这不能回答问题。在您的域上拥有无法“修改以返回 JSON”的第 3 方应用程序的用例如何?
【解决方案4】:

您可以使用jquery.soap plugin 为您完成工作。

此脚本使用 $.ajax 发送 SOAPEnvelope。它可以将 XML DOM、XML 字符串或 JSON 作为输入,并且响应也可以作为 XML DOM、XML 字符串或 JSON 返回。

来自网站的使用示例:

$.soap({
    url: 'http://my.server.com/soapservices/',
    method: 'helloWorld',

    data: {
        name: 'Remy Blom',
        msg: 'Hi!'
    },

    success: function (soapResponse) {
        // do stuff with soapResponse
        // if you want to have the response as JSON use soapResponse.toJSON();
        // or soapResponse.toString() to get XML string
        // or soapResponse.toXML() to get XML DOM
    },
    error: function (SOAPResponse) {
        // show error
    }
});

【讨论】:

    【解决方案5】:

    有人试过吗? https://github.com/doedje/jquery.soap

    看起来很容易实现。

    例子:

    $.soap({
    url: 'http://my.server.com/soapservices/',
    method: 'helloWorld',
    
    data: {
        name: 'Remy Blom',
        msg: 'Hi!'
    },
    
    success: function (soapResponse) {
        // do stuff with soapResponse
        // if you want to have the response as JSON use soapResponse.toJSON();
        // or soapResponse.toString() to get XML string
        // or soapResponse.toXML() to get XML DOM
    },
    error: function (SOAPResponse) {
        // show error
    }
    });
    

    会导致

    <soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <helloWorld>
            <name>Remy Blom</name>
            <msg>Hi!</msg>
        </helloWorld>
      </soap:Body>
    </soap:Envelope>
    

    【讨论】:

      【解决方案6】:

      托马斯:

      JSON 是前端使用的首选,因为我们可以轻松查找。因此,您无需处理 XML。因此,如果不使用库,SOAP 会很痛苦。有人提到 SOAPClient,这是一个很好的库,我们从它开始用于我们的项目。然而它有一些限制,我们不得不重写它的大部分。它以SOAPjs 发布,支持将复杂对象传递给服务器,并包含一些示例代理代码以使用来自其他域的服务。

      【讨论】:

      • “JSON 是前端使用的首选,因为它是 javascript。” - JSON 不是 JavaScript。 (它看起来就像 JavaScript。)
      • en.wikipedia.org/wiki/JSON -- 字面意思是“JavaScript Object Notation”,虽然我同意 JSON 是一种规范而不是一种语言,因此绝对是“不是 javascript”,但你必须同意它的方式命名很容易混淆人们。
      • "JSON 是前端使用的首选,因为它是 javascript" 请删除它,它正在传播虚假信息:timelessrepo.com/json-isnt-a-javascript-subset
      【解决方案7】:
      <html>
       <head>
          <title>Calling Web Service from jQuery</title>
          <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
          <script type="text/javascript">
              $(document).ready(function () {
                  $("#btnCallWebService").click(function (event) {
                      var wsUrl = "http://abc.com/services/soap/server1.php";
                      var soapRequest ='<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:Body> <getQuote xmlns:impl="http://abc.com/services/soap/server1.php">  <symbol>' + $("#txtName").val() + '</symbol>   </getQuote> </soap:Body></soap:Envelope>';
                                     alert(soapRequest)
                      $.ajax({
                          type: "POST",
                          url: wsUrl,
                          contentType: "text/xml",
                          dataType: "xml",
                          data: soapRequest,
                          success: processSuccess,
                          error: processError
                      });
      
                  });
              });
      
              function processSuccess(data, status, req) { alert('success');
                  if (status == "success")
                      $("#response").text($(req.responseXML).find("Result").text());
      
                      alert(req.responseXML);
              }
      
              function processError(data, status, req) {
              alert('err'+data.state);
                  //alert(req.responseText + " " + status);
              } 
      
          </script>
      </head>
      <body>
          <h3>
              Calling Web Services with jQuery/AJAX
          </h3>
          Enter your name:
          <input id="txtName" type="text" />
          <input id="btnCallWebService" value="Call web service" type="button" />
          <div id="response" ></div>
      </body>
      </html>
      

      Hear is best JavaScript with SOAP tutorial with example.

      http://www.codeproject.com/Articles/12816/JavaScript-SOAP-Client

      【讨论】:

        【解决方案8】:

        Easily consume SOAP Web services with JavaScript -> Listing B

        function fncAddTwoIntegers(a, b)
        {
            varoXmlHttp = new XMLHttpRequest();
            oXmlHttp.open("POST",
         "http://localhost/Develop.NET/Home.Develop.WebServices/SimpleService.asmx'",
         false);
            oXmlHttp.setRequestHeader("Content-Type", "text/xml");
            oXmlHttp.setRequestHeader("SOAPAction", "http://tempuri.org/AddTwoIntegers");
            oXmlHttp.send(" \
        <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:Body> \
            <AddTwoIntegers xmlns='http://tempuri.org/'> \
              <IntegerOne>" + a + "</IntegerOne> \
              <IntegerTwo>" + b + "</IntegerTwo> \
            </AddTwoIntegers> \
          </soap:Body> \
        </soap:Envelope> \
        ");
            return oXmlHttp.responseXML.selectSingleNode("//AddTwoIntegersResult").text;
        }
        

        这可能无法满足您的所有要求,但它是实际回答您问题的开始。 (我将 XMLHttpRequest() 切换为 ActiveXObject("MSXML2.XMLHTTP"))。

        【讨论】:

          【解决方案9】:

          这里有一些很棒的示例(以及一个现成的 JavaScript SOAP 客户端!): http://plugins.jquery.com/soap/

          查看自述文件,注意同源浏览器限制。

          【讨论】:

            【解决方案10】:

            问题是“使用 Javascript 的最简单的 SOAP 示例是什么?”

            此答案是Node.js 环境中的示例,而不是浏览器。 (我们将脚本命名为soap-node.js)我们将以the public SOAP web service from Europe PMC为例,获取一篇文章的参考列表。

            const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
            const DOMParser = require('xmldom').DOMParser;
            
            function parseXml(text) {
                let parser = new DOMParser();
                let xmlDoc = parser.parseFromString(text, "text/xml");
                Array.from(xmlDoc.getElementsByTagName("reference")).forEach(function (item) {
                    console.log('Title: ', item.childNodes[3].childNodes[0].nodeValue);
                });
            
            }
            
            function soapRequest(url, payload) {
                let xmlhttp = new XMLHttpRequest();
                xmlhttp.open('POST', url, true);
            
                // build SOAP request
                xmlhttp.onreadystatechange = function () {
                    if (xmlhttp.readyState == 4) {
                        if (xmlhttp.status == 200) {
                            parseXml(xmlhttp.responseText);
                        }
                    }
                }
            
                // Send the POST request
                xmlhttp.setRequestHeader('Content-Type', 'text/xml');
                xmlhttp.send(payload);
            }
            
            soapRequest('https://www.ebi.ac.uk/europepmc/webservices/soap', 
                `<?xml version="1.0" encoding="UTF-8"?>
                <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
                <S:Header />
                <S:Body>
                    <ns4:getReferences xmlns:ns4="http://webservice.cdb.ebi.ac.uk/"
                        xmlns:ns2="http://www.scholix.org"
                        xmlns:ns3="https://www.europepmc.org/data">
                        <id>C7886</id>
                        <source>CTX</source>
                        <offSet>0</offSet>
                        <pageSize>25</pageSize>
                        <email>ukpmc-phase3-wp2b---do-not-reply@europepmc.org</email>
                    </ns4:getReferences>
                </S:Body>
                </S:Envelope>`);
            

            在运行代码之前,需要安装两个包:

            npm install xmlhttprequest
            npm install xmldom
            

            现在你可以运行代码了:

            node soap-node.js
            

            你会看到如下输出:

            Title:  Perspective: Sustaining the big-data ecosystem.
            Title:  Making proteomics data accessible and reusable: current state of proteomics databases and repositories.
            Title:  ProteomeXchange provides globally coordinated proteomics data submission and dissemination.
            Title:  Toward effective software solutions for big biology.
            Title:  The NIH Big Data to Knowledge (BD2K) initiative.
            Title:  Database resources of the National Center for Biotechnology Information.
            Title:  Europe PMC: a full-text literature database for the life sciences and platform for innovation.
            Title:  Bio-ontologies-fast and furious.
            Title:  BioPortal: ontologies and integrated data resources at the click of a mouse.
            Title:  PubMed related articles: a probabilistic topic-based model for content similarity.
            Title:  High-Impact Articles-Citations, Downloads, and Altmetric Score.
            

            【讨论】:

            • 这对我有用,但我个人更喜欢使用 axios。 let xlms = "schemas.xmlsoap.org/soap/envelope">
              ...
              " axios .post('ebi.ac.uk/europepmc/webservices/soap', xmls, { headers: { 'Content-Type': 'text/xml' } }) .then(res => { 控制台.log(res); }) .catch(err => { console.log(err); });
            【解决方案11】:

            最简单的例子包括:

            1. 获取用户输入。
            2. 编写类似这样的 XML SOAP 消息

              <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:Body>
                  <GetInfoByZIP xmlns="http://www.webserviceX.NET">
                    <USZip>string</USZip>
                  </GetInfoByZIP>
                </soap:Body>
              </soap:Envelope>
              
            3. 使用 XHR 将消息发布到 Web 服务 url

            4. 类似这样解析webservice的XML SOAP响应

              <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                             xmlns:xsd="http://www.w3.org/2001/XMLSchema">
               <soap:Body>
                <GetInfoByZIPResponse xmlns="http://www.webserviceX.NET">
                 <GetInfoByZIPResult>
                  <NewDataSet xmlns="">
                   <Table>
                    <CITY>...</CITY>
                    <STATE>...</STATE>
                    <ZIP>...</ZIP>
                    <AREA_CODE>...</AREA_CODE>
                    <TIME_ZONE>...</TIME_ZONE>
                   </Table>
                  </NewDataSet>
                 </GetInfoByZIPResult>
                </GetInfoByZIPResponse>
               </soap:Body>
              </soap:Envelope>
              
            5. 向用户展示结果。

            但是没有外部 JavaScript 库会很麻烦。

            【讨论】:

            • 甚至不是您没有回答的第一部分 - 是功能性的(换句话说,实际工作)。
            【解决方案12】:
            function SoapQuery(){
              var namespace = "http://tempuri.org/";
              var site = "http://server.com/Service.asmx";
              var xmlhttp = new ActiveXObject("Msxml2.ServerXMLHTTP.6.0");
              xmlhttp.setOption(2,  13056 );  /* if use standard proxy */
              var args,fname =  arguments.callee.caller.toString().match(/ ([^\(]+)/)[1]; /*Имя вызвавшей ф-ции*/
              try { args =   arguments.callee.caller.arguments.callee.toString().match(/\(([^\)]+)/)[1].split(",");  
                } catch (e) { args = Array();};
              xmlhttp.open('POST',site,true);  
              var i, ret = "", q = '<?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:Body><'+fname+ ' xmlns="'+namespace+'">';
              for (i=0;i<args.length;i++) q += "<" + args[i] + ">" + arguments.callee.caller.arguments[i] +  "</" + args[i] + ">";
              q +=   '</'+fname+'></soap:Body></soap:Envelope>';
                        // Send the POST request
                        xmlhttp.setRequestHeader("MessageType","CALL");
                        xmlhttp.setRequestHeader("SOAPAction",namespace + fname);
                        xmlhttp.setRequestHeader('Content-Type', 'text/xml');
                        //WScript.Echo("Запрос XML:" + q);
                        xmlhttp.send(q);
                 if  (xmlhttp.waitForResponse(5000)) ret = xmlhttp.responseText;
                return ret;
              };
            
            
            
            
            
            function GetForm(prefix,post_vars){return SoapQuery();};
            function SendOrder2(guid,order,fio,phone,mail){return SoapQuery();};
            
            function SendOrder(guid,post_vars){return SoapQuery();};
            

            【讨论】:

              【解决方案13】:

              Angularjs $http 包装基于XMLHttpRequest。只要在标题内容设置下面的代码就可以了。

              "Content-Type": "text/xml; charset=utf-8"
              

              例如:

              function callSoap(){
              var url = "http://www.webservicex.com/stockquote.asmx";
              var soapXml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://www.webserviceX.NET/\"> "+
                       "<soapenv:Header/> "+
                       "<soapenv:Body> "+
                       "<web:GetQuote> "+
                       "<web:symbol></web:symbol> "+
                       "</web:GetQuote> "+
                       "</soapenv:Body> "+
                       "</soapenv:Envelope> ";
              
                  return $http({
                        url: url,  
                        method: "POST",  
                        data: soapXml,  
                        headers: {  
                            "Content-Type": "text/xml; charset=utf-8"
                        }  
                    })
                    .then(callSoapComplete)
                    .catch(function(message){
                       return message;
                    });
              
                  function callSoapComplete(data, status, headers, config) {
                      // Convert to JSON Ojbect from xml
                      // var x2js = new X2JS();
                      // var str2json = x2js.xml_str2json(data.data);
                      // return str2json;
                      return data.data;
              
                  }
              
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2020-03-12
                • 1970-01-01
                • 1970-01-01
                • 2017-09-27
                • 2016-12-17
                • 2019-05-24
                • 2012-04-12
                相关资源
                最近更新 更多