从JQuery调用WCF服务:跨原点OPTIONS请求给出错误400 [英] Call WCF service from JQuery : cross-origin OPTIONS request gives error 400

查看:708
本文介绍了从JQuery调用WCF服务:跨原点OPTIONS请求给出错误400的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



在端口80上的 IIS 上,客户端从在端口81上的Apache 运行,两者都从 localhost


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


  2. 使用Firefox时,会出现错误(JavaScript警告显示 null | error | )。看起来 POST 请求未发送,因为 OPTIONS 请求失败:


  3. 使用IE,好像它是从同一起源...我没有看到任何选项请求:


 命名空间test 
{
[ServiceContract]
public interface IMathService
{
[OperationContract]
String HelloWorld();
}
}

服务配置(Web.config):

 < services> 
< service name =Test.MathServicebehaviorConfiguration =ServiceBehavior>
< host>
< baseAddresses>
< add baseAddress =http:// localhost:80 / WCFtest / service.svc/>
< / baseAddresses>
< / host>
< endpoint address =/ soapbinding =basicHttpBindingcontract =Test.IMathService/>
< endpoint address =/ restbinding =webHttpBindingcontract =Test.IMathServicebehaviorConfiguration =WEB/>
< / service>
< / services>
[...]
< httpProtocol>
< customHeaders>
< add name =Access-Control-Allow-Originvalue =http:// localhost:81/>
< add name =Access-Control-Allow-Headersvalue =SOAPAction,Content-type,Accept,Origin/>
< add name =Access-Control-Allow-Methodsvalue =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' )。文本());
},
错误:function(jqxhr,textStatus,errorThrown){
alert(jqxhr.responseXML +'|'+ textStatus +'|'+ errorThrown);
}
});
});

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



我错过了什么吗?

解决方案

花费2天追逐鬼(各种版本的CORS通过浏览器)自己我认为结论是:这里的问题是OPTIONS请求 - FF和Opera发送它,但我不认为IE。另外我不认为OPTIONS是一个允许的动词默认情况下IIS,IIS快递等
我添加Application_BeginRequest在我的global.asax:

  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。


I am trying to call a C# WCF SOAP Web service from JQuery.

The service is hosted on IIS on port 80, client is run from Apache on port 81, both from localhost. So I fall into cross-origin requests.

  1. Using Chrome, I get expected results, but looking at the network traffic, it shows that the OPTIONS request returns error 400 Bad Request, However the next POST request succeeds :

  2. Using Firefox, error is raised (JavaScript alert shows null | error |). It seems the POST request is not sent because the OPTIONS request failed:

  3. Using IE, all is working fine, as if it was from the same origin... I don't see any OPTIONS request:

The exposed function from the interface :

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

Service configuration (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 code:

$('#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);
        }
    });
});

Service is working fine if called from the same origin.

Did I missed something?

解决方案

After spending 2 days chasing ghosts (various versions of "interpretations" of CORS by the browsers) myself I think the conclusion is : the problem here is the OPTIONS request - FF and Opera are sending it, but I don't think IE does. Also I don't think OPTIONS is an allowed verb by default by IIS, IIS express, etc. I added Application_BeginRequest in my global.asax:

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();
    }
}

As a result I managed to get my request through with FF.

这篇关于从JQuery调用WCF服务:跨原点OPTIONS请求给出错误400的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆