jquery - 从 JQuery 调用 WCF 服务 : cross-origin OPTIONS request gives error 400

标签 jquery wcf web-services soap cross-domain

我正在尝试从 JQuery 调用 C# WCF SOAP Web 服务

该服务托管在端口 80 上的 IIS 上,客户端从端口 81 上的 Apache 运行,两者均来自 localhost。所以我陷入了跨源请求。

  1. 使用 Chrome,我得到了预期的结果,但查看网络流量,它显示 OPTIONS 请求返回错误 400 Bad Request,但是下一个POST 请求成功: enter image description here

  2. 使用 Firefox,会引发错误(JavaScript 警报显示 null | error |)。看来 POST 请求未发送,因为 OPTIONS 请求失败: enter image description here

  3. 使用 IE,一切正常,就好像它来自同一个源一样...我没有看到任何 OPTIONS 请求: enter image description here

接口(interface)暴露的函数:

namespace Test
{
    [ServiceContract]
    public interface IMathService
    {
        [OperationContract]
        String HelloWorld();
    }
}

服务配置(Web.config):

<services>
  <service name="Test.MathService" behaviorConfiguration="ServiceBehavior">
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:80/WCFtest/service.svc" />
      </baseAddresses>
    </host>
    <endpoint address="/soap" binding="basicHttpBinding" contract="Test.IMathService" />
    <endpoint address="/rest" binding="webHttpBinding" contract="Test.IMathService" behaviorConfiguration="WEB" />
  </service>
</services>
[...]
<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="http://localhost:81" />
    <add name="Access-Control-Allow-Headers" value="SOAPAction, Content-type, Accept, Origin" />
    <add name="Access-Control-Allow-Methods" value="POST, GET, PUT, DELETE, OPTIONS" />
  </customHeaders>
</httpProtocol>

JQuery 代码:

$('#btn_helloworld').click(function () {
    var soapRequest = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">' +
                        '<soapenv:Header/>' +
                        '<soapenv:Body>' +
                            '<tem:HelloWorld/>' +
                        '</soapenv:Body>' +
                        '</soapenv:Envelope>';
    $.ajax({
        type: 'POST',
        url: 'http://localhost/WCFtest/service.svc/soap',
        crossDomain: true,
        contentType: 'text/xml',
        dataType: 'xml',
        data: soapRequest,
        beforeSend: function (xhr) {
            xhr.setRequestHeader('SOAPAction', 'http://tempuri.org/IMathService/HelloWorld');
        },
        success: function (data) {
            $('#outputHelloWorld').val($(data).find('HelloWorldResponse').text());
        },
        error: function (jqxhr, textStatus, errorThrown) {
            alert(jqxhr.responseXML + ' | ' + textStatus + ' | ' + errorThrown);
        }
    });
});

如果从同一来源调用,服务工作正常。

我错过了什么吗?

最佳答案

我自己花了两天时间追鬼(浏览器对 CORS 的各种“解释”版本),我认为结论是:这里的问题是 OPTIONS 请求 - FF 和 Opera 正在发送它,但我不认为IE 确实如此。另外,我不认为 OPTIONS 是 IIS、IIS Express 等默认允许的动词。 我在我的 global.asax 中添加了 Application_BeginRequest:

void Application_BeginRequest(Object sender, EventArgs e)
{
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");

        HttpContext.Current.Response.End();
    }
}

结果我成功地通过了 FF 的请求。

关于jquery - 从 JQuery 调用 WCF 服务 : cross-origin OPTIONS request gives error 400,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18874320/

相关文章:

jquery,克隆问题并保持唯一的ID!

javascript - 在 jQuery 中单击“提交”按钮更新全局计数器变量

jquery - 如何使菜单在单击父/子项后保持可见

ios - 通过RESTful WCF服务从iPhone应用程序访问SQL数据库

c# - 如何从 Internet 获取 DateTime(外部资源 - 不是来自服务器)

java - Spring Restful Webservice 上传 CSV

javascript - Chrome 上 iframe 中的分页符不起作用?

c# - 如何获得 "200 OK"的 HttpWebResponse?

c# - 复制大型 List<T> 并防止更改原始列表

java - 如何处理 SOAP 调用中的方法及其参数