3

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. OPTIONSIE を使用すると、あたかも同じオリジンからのものであるかのように、すべて正常に動作しています...リクエスト が表示されません。ここに画像の説明を入力

インターフェイスから公開された関数:

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

同じオリジンから呼び出された場合、サービスは正常に機能しています。

私は何かを逃しましたか?

4

1 に答える 1

8

ゴースト(ブラウザによるCORSの「解釈」のさまざまなバージョン)を追跡するのに2日間費やした後、結論は次のとおりだと思います:ここでの問題は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でリクエストを通過させることができました。

于 2013-11-13T13:35:07.003 に答える