【问题标题】:Post a SOAP request in HTML and get response以 HTML 格式发布 SOAP 请求并获得响应
【发布时间】:2019-08-14 21:37:46
【问题描述】:

我正在使用WCFStorm 来调试一个非常简单的 SOAP 端点:

http://www.dneonline.com/calculator.asmx?WSDL

可以使用这样的端点来请求 4 个基本算术计算并检索响应:在示例中,我请求数字 35 并收到响应 8,一切都很好!

我现在想创建一个无需使用 WCFStorm 即可完成相同任务的 HTML 页面。这是我的代码:

<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://www.dneonline.com/calculator.asmx?WSDL";
                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://www.dneonline.com/calculator.asmx?WSDL">  <intA>' + $("#intA").val() + '</intA> <intB>' + $("#intB").val() + '</intB>  </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("Int32").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 the numbers:
    <input id="intA" type="string" />
    <input id="intB" type="string" />
    <input id="btnCallWebService" value="Call web service" type="button" />
    <div id="response"></div>
</body>

</html>

但不幸的是,我只能收到一个:errundefined。 我哪里错了?

【问题讨论】:

  • 转储所有的值数据、状态、请求,看看你在控制台中得到了什么

标签: jquery html api soap wsdl


【解决方案1】:

我哪里错了?

  1. 请求负载/数据格式不正确

    对于 SOAP 1.1:(请求和响应格式为 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>
        <Add xmlns="http://tempuri.org/">
          <intA>int</intA>
          <intB>int</intB>
        </Add>
      </soap:Body>
    </soap:Envelope>
    

    对于 SOAP 1.2:(请求和响应格式为 SOAP + XML)

    <?xml version="1.0" encoding="utf-8"?>
    <soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
      <soap12:Body>
        <Add xmlns="http://tempuri.org/">
          <intA>int</intA>
          <intB>int</intB>
        </Add>
      </soap12:Body>
    </soap12:Envelope>
    

    详情请参阅计算器网络服务docs

  2. 正如我在原始答案中指出的那样,这是需要考虑的非常重要的事情:计算器 Web 服务端点 (http://www.dneonline.com/calculator.asmx?WSDL) 没有发出 CORS 请求时所需的正确 CORS 标头 (Access-Control-Allow-Origin) — 摘自 MDN 的 article 关于跨域资源共享 (CORS)

    Web 应用程序在执行 跨域 HTTP 请求时执行 请求具有不同来源(域、协议或 端口)而不是它自己的来源。

    跨域请求示例:前端 JavaScript 代码 从 http://domain-a.com 提供的 Web 应用程序使用 XMLHttpRequest 请求http://api.domain-b.com/data.json

    出于安全原因,浏览器会限制跨域 HTTP 请求 从脚本中启动。例如,XMLHttpRequestFetch API 关注same-origin policy。 这意味着使用这些 API 的 Web 应用程序只能请求 来自加载应用程序的同一来源的 HTTP 资源, 除非来自其他来源的响应包含正确的 CORS 标题。

因此,如果上述(第二段)适用于您,即您实际上并未从同一来源/域发出 CORS/AJAX 请求,那么您可以:

  1. 如果您拥有计算器 Web 服务 (dneonline.com) 的域/网站.. 或可以控制其管理,请在该网站上enable CORS

  2. 或者,如果您的站点有 PHP 或 Python 等服务器端应用程序,那么您可以使用服务器端脚本发出请求 - 示例在 PHP 中 strong>,您可以使用 calculator.php 向 API 发出远程请求,然后您的脚本向 calculator.php 发出 AJAX 请求。

  3. 或者您可以使用 CORS 代理 例如 https://cors-anywhere.herokuapp.com,我已经尝试过 — 查看下面的演示。

演示:使用 https://cors-anywhere.herokuapp.com 向未启用 CORS 的资源发出 AJAX 请求

$('#btnCallWebService').click(function(event) {
  $('#intA').val(Number($('#intA').val() || 0).toFixed(0) || 0);
  $('#intB').val(Number($('#intB').val() || 0).toFixed(0) || 0);
  if ('0' === $('#intA').val() && '0' === $('#intB').val()) {
    alert('Non-zeros only.. for this demo.');
    return;
  }

  var $btn = $(this), _btn_text = $btn.val();
  $btn.prop('disabled', true).val('Calculating..');
  $('#response').hide();

  var wsUrl = 'http://www.dneonline.com/calculator.asmx';
  var soap12Request = '<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">  <soap12:Body>    <Add xmlns="http://tempuri.org/">      <intA>' + $('#intA').val() + '</intA>      <intB>' + $('#intB').val() + '</intB>    </Add>  </soap12:Body></soap12:Envelope>';

  $.ajax({
    type: 'POST',
    url: 'https://cors-anywhere.herokuapp.com/' + wsUrl,
    contentType: 'application/soap+xml', // can also be text/xml
    dataType: 'xml',
    data: soap12Request,
    success: function(xml){
      var $doc = $(xml);
      $('#answer').html($doc.find('AddResult').text());
      $('#response').show();
    },
    complete: function(){
      $btn.val(_btn_text).prop('disabled', false);
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Enter the numbers:
<input id="intA" type="number" placeholder="No decimals" /> <code>+</code>
<input id="intB" type="number" placeholder="No decimals" />
<input id="btnCallWebService" value="Call web service (SOAP 1.2)" type="button" />
<div id="response" style="display:none">
  The answer is: <b id="answer"></b>
</div>

【讨论】:

  • PS:答案假设网站 (dneonline.com) 不是您的。否则,你可以enable CORS
  • 谢谢,但我需要 HTML 和 JQuery。 PHP 不是一个选项
  • 重点是关于 dneonline.com 的计算器 Web 服务端点上未启用 CORS。但无论如何,请参阅更新的答案 - 我希望它值得一票?..
  • 感谢您的准确回答。我不是网站的所有者。你有我可以用来测试的启用了 CORS 的 URL 示例吗?谢谢一百万
  • 如果您指的是任何 URL,那么您可以向 http://stormy-refuge-68458.herokuapp.com/todos/&lt;id&gt;/ 发出 AJAX 请求,其中 &lt;id&gt; 是介于 1200 之间的整数。请求成功后,您会收到一个虚拟 JSON 响应。
【解决方案2】:

由于同源政策,不可能在http://www.example.com 上拥有一个页面并对http://www.anotherdomain.com 进行ajax 调用。

解决方案?

  • 在 WCF 服务上启用 CORS
  • 或者,创建一个后端代理来使用 WCF,然后对此进行 ajax 调用

如果您无法将您的 javascript 移动到与 Web 服务相同的域中,唯一可靠的方法是构建一个服务器端脚本,该脚本将托管在与您的 javascript 代码相同的域中。因此,您将向服务器端脚本发送 AJAX 请求,该脚本将调用远程 Web 服务并返回结果。以下链接展示了如何创建一个简单的服务器端 ASP.Net MVC 来使用 WCF 服务:

jQuery SOAP 提供了一个 jQuery 插件,用于使用 SOAP 与 Web 服务进行通信,假设您的 javascript 和 Web 服务在同一个域中。

【讨论】:

  • 所以我需要像 XAMPP 这样的东西?
  • XAMPP for php 和 IIS for ASP 是托管后端应用程序的不错选择。
【解决方案3】:

Sally CJ 对这篇文章做出了很好的回复,我相信应该是那个给出正确回应的人。 我学到了很多关于 CORS 的知识。

但我不得不提到,有一种方法可以使用简单的 HTML 文件来归档结果:

Calling WebService Using AJAX jQuery With SOAP

【讨论】:

    猜你喜欢
    • 2020-02-08
    • 1970-01-01
    • 2017-07-29
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    相关资源
    最近更新 更多