【问题标题】:Trouble calling web service using JQuery使用 JQuery 调用 Web 服务时遇到问题
【发布时间】:2013-04-06 19:25:01
【问题描述】:

我在从 JQuery 调用 Web 服务时遇到问题。

我正在访问的网址是:http://www.deeptraining.com/webservices/weather.asmx?WSDL,其中有一个名为GetWeather 的操作。 我正在使用 Firefox,我收到以下消息:

Firefox 控制台:[19:43:29.849] 选项 http://www.deeptraining.com/webservices/weather.asmx?op=GetWeather [HTTP/1.1 200 OK 371ms]

警告:未定义的解析器错误

如果得到代码200,表示请求发送成功? 我究竟做错了什么?提出请求的正确方法是什么? 谢谢!!

这是我的代码:

<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.deeptraining.com/webservices/weather.asmx?op=GetWeather";

            var soapRequest ='<?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> \
                                    <GetWeather xmlns="http://litwinconsulting.com/webservices/"> \
                                      <City>new york</City> \
                                    </GetWeather> \
                                  </soap:Body> \
                                </soap:Envelope>';

            $.ajax({
                type: "POST",
                url: wsUrl,
                contentType: "text/xml",
                dataType: "xml",
                data: soapRequest,
                success: processSuccess,
                error: processError
            });

        });
    });
    function processSuccess(data, status, req) {
        if (status == "success")
            alert('SUCCESS');
    }

    function processError(data, status, req) {
        alert(req.responseText + " " + status);
    }
    </script>
    </head>
    <body>
        <h3>
            Calling Web Services with jQuery/AJAX
        </h3>
        <input id="btnCallWebService" value="Call web service" type="button" />
        <div id="response" />
    </body>
</html>

【问题讨论】:

  • 你的这个 HTML,你是在测试时部署在http://www.deeptraining.com/ 的服务器上吗?

标签: jquery web-services cors


【解决方案1】:

(下面的答案假设您没有在http://www.deeptraining.com/ 中部署此HTML 文件。)

您的代码实际上是在尝试发出 CORS 请求,而不是普通的 POST。

现代浏览器只允许 Ajax 调用与源 HTML 页面相同域中的页面。

换句话说,只要尝试发出 Ajax 请求的 HTML 页面与目标 URL(在您的情况下为 www.deeptraining.com)不在同一个域中,浏览器就不会进行调用(因为您的d 期望)。相反,它将尝试发出 CORS 请求。

CORS 请求? !@#$¨& 是吗?

Wikipedia says跨域资源共享 (CORS) 是一种允许网页将XMLHttpRequests 发送到另一个域的机制。否则,由于 same origin security policy 的原因,Web 浏览器会禁止此类“跨域”请求。

简而言之,要执行 CORS 请求,您的浏览器:

  • 将首先向目标 URL 发送OPTION 请求

  • 然后仅当服务器对该OPTION 的响应包含adequate headers 以允许CORS 请求,浏览器将执行调用(几乎与HTML 页面的调用方式完全相同)在同一个域中)。

    • 如果没有出现预期的标头,浏览器就会放弃(就像它对您所做的那样)。

如何解决?

不幸的是,除了将该 HTML 文件部署到位于 http://www.deeptraining.com/ 的服务器中之外,您无能为力。

JSONP 怎么样?

要在这种情况下使用 JSONP,您必须更改服务以通过 GET 返回信息,因为您无法使用 JSONP 进行 POST。 (This answer 指出了一些黑客行为,但我认为这太过分了。)

哦,天哪,没有解决方法,那么?

真的没有干净的解决方法。您可以设置一个应用程序(在您的 HTML 文件的同一域中)将每个 TCP/IP 请求转发到http://www.deeptraining.com/,然后欺骗您的浏览器。或者,您可以在您的域中设置该 Web 服务的镜像。你看,从现在开始一切都变得太脏了,祝你好运。

【讨论】:

  • 感谢您的回答。我是 ajax 问题的新手,但如果我理解正确的更简单的方法是放在同一台服务器中,我的 Web 服务部署了执行 ajax 调用的 html。所以,我可以从客户端创建一个表单来调用将放置在服务器上的 hmtl,然后 ajax 调用将与我的 Web 服务位于同一域,对吗??
  • 是的,正确!或者...您可以更改 Web 服务代码以允许 CORS(它只涉及设置一些 http 标头 - 但在 REST Web 服务中设置它比基于 SOAP 的服务更容易)。
  • 最后,我把两个资源都放在了同一个服务器上,避免了 cors 的麻烦,效果很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多