简体   繁体   English

如何配置通过跨域AJAX调用的WCF服务

[英]How Do I Configure a WCF Service to Be Called Via Cross-Domain AJAX

I'm having a little difficulty configuring my WCF service to allow consumption via cross-domain AJAX. 我在配置WCF服务以允许通过跨域AJAX进行消费时遇到了一些困难。

I've successfully used this service on a client with no problems, but everytime I try to hit it using AJAX (via the $.ajax object in jQuery), I get a 400 error. 我已经成功地在客户端上成功使用了该服务,但是每次尝试使用AJAX来实现该服务时(通过jQuery中的$ .ajax对象),都会出现400错误。

Here is my web.config 这是我的web.config

<?xml version="1.0"?>
<configuration>
    <system.web>
        <compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
    </system.web>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="basicHttpBinding" />
            </basicHttpBinding>
            <mexHttpBinding>
                <binding name="mexHttpBinding" />
            </mexHttpBinding>
            <webHttpBinding>
                <binding name="webHttpBinding" crossDomainScriptAccessEnabled="true">
                    <security mode="None" />
                </binding>
            </webHttpBinding>
        </bindings>
        <services>
            <service name="Services.WebAnalyticsService">
                <clear />
                <endpoint binding="basicHttpBinding" bindingConfiguration="basicHttpBinding"
                 name="WebAnalyticsDotNetClientEndpoint" contract="Contracts.IWebAnalyticsService"
                 listenUriMode="Explicit" />
                <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="mexHttpBinding"
                 name="WebAnalyticsMetaDataEndpoint" contract="Contracts.IWebAnalyticsService"
                 listenUriMode="Explicit" />
                <endpoint address="script" behaviorConfiguration="aspNetAjaxBehavior"
                 binding="webHttpBinding" bindingConfiguration="webHttpBinding"
                 name="WebAnalyticsAjaxEndpoint" contract="Contracts.IWebAnalyticsService" />
                <!--<endpoint address="web" behaviorConfiguration="RESTBehavior"
                 binding="webHttpBinding" bindingConfiguration="webHttpBinding"
                 name="WebAnalyticsAjaxEndpoint" contract="Contracts.IWebAnalyticsServiceWeb"  />-->
            </service>
        </services>
        <behaviors>
            <endpointBehaviors>
                <behavior name="aspNetAjaxBehavior">
                    <enableWebScript />
                </behavior>
                <!--<behavior name="RESTBehavior">
                    <webHttp helpEnabled="true"/>
                </behavior>-->
            </endpointBehaviors>
            <serviceBehaviors>
                <behavior>
                    <serviceMetadata httpGetEnabled="true" />
                    <serviceDebug includeExceptionDetailInFaults="true" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>
    </system.serviceModel>
    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
    </system.webServer>
        <system.diagnostics>
            <sources>
                <source name="System.ServiceModel"
                    switchValue="Information, ActivityTracing"
                    propagateActivity="true">
                    <listeners>
                        <add name="xml"
                 type="System.Diagnostics.XmlWriterTraceListener"
                 initializeData="c:\log\Traces.svclog" />
                    </listeners>
                </source>
            </sources>
        </system.diagnostics>
</configuration>

And this is my operation contract. 这是我的运营合同。

Namespace Contracts

        <ServiceContract()>
 Public Interface IWebAnalyticsService

    <OperationContract(), WebGet(RequestFormat:=WebMessageFormat.Json)>
    Sub SendWaEvent(ByVal eventID As Integer, ByVal eventValue As String, _
      ByVal cookieVisitID As String, ByVal cookieVisitorSession As String, _
      ByVal HTTPXForwardedServer As String, ByVal HTTPXRewriteURL As String, _
      ByVal ScriptName As String, ByVal ServerName As String)

    End Interface

End Namespace

My Ajax call is pretty straightforward, but here it is: 我的Ajax调用非常简单,但是这里是:

$.ajax({
  type: 'POST',
  crossDomain: true,
  url: 'http://localhost:37490/services/webanalyticservice.svc/SendWaEvent',
  data: Data, //Data is a JSON wrapper I've previously constructed.
  contentType: 'application/javascript;charset=UTF-8'
  success: function(result) {DoSomething(result);},
  error: HandleError
});

[ UPDATES BELOW ] [ 更新如下 ]

It's always the things we overlook, isn't it? 总是我们忽略的东西,不是吗? Anyhow, after being very dismissive of the "straightforward" AJAX call above, it ended up being the problem. 无论如何,在对上面的“直接” AJAX调用非常不屑一顾之后,它最终成为了问题。 To get this working, I had to change my AJAX call to this: 为了使它正常工作,我不得不将我的AJAX调用更改为:

        function SendAJAX() {
            $.ajax({ type: "GET",
                url: URL,
                data: Data,
                dataType: 'jsonp',
                jsonpCallback: 'MyCallBack',
                timeout: 10000,
                crossDomain: true,
                contentType: 'application/json; charset=UTF-8',
                success: function (data, textStatus, jqXHR) { WriteSuccess(data, textStatus, jqXHR) },
                error: function (jqXHR, textStatus, errorThrown) { WriteError(jqXHR, textStatus, errorThrown) },
                complete: function (jqXHR, textStatus) { }
            });
        }

Also, please note that if you are going to be testing locally, you'll need to add the following to your web config or you'll receive a 500 error saying that cross-domain javascript isn't allowed in authenticated services. 另外,请注意,如果您要在本地进行测试,则需要将以下内容添加到您的网络配置中,否则将收到500错误消息,提示已验证的服务中不允许使用跨域JavaScript。

<system.web>
    <authentication mode="None" />
</system.web>

You can remove this attribute in your web.release.config using xdt:transform . 您可以使用xdt:transform在web.release.config中删除此属性。

Huge shout out to @Rajesh! 向@Rajesh大声喊叫! Great job, man! 干得好,伙计!

Your JQuery function needs to looks as shown below: 您的JQuery函数需要如下所示:

function TestingWCFRestWithJsonp() {
                $.ajax({
                    url: "http://localhost:37490/services/webanalyticservice.svc/script/SendWaEvent",
                    dataType: "jsonp",
                    type: "GET",
                    timeout: 10000,
                    jsonpCallback: "MyCallback",
                    success: function (data, textStatus, jqXHR) {
                    },
                    error: function (jqXHR, textStatus, errorThrown) {    
                    },
                    complete: function (jqXHR, textStatus) {
                    }
                });
            }
            function MyCallback(data) {
                alert(data);
            }

Since your endpoint element has the address value set you would need to append that to the end of .svc and then provide the method name as in the sample below. 由于您的终结点元素设置了地址值,因此需要将其附加到.svc的末尾,然后提供方法名称,如下面的示例中所示。

The crossDomainScriptAccessEnabled property on the binding element identifies if your request has a callback method specified and writes the response back to stream. 绑定元素上的crossDomainScriptAccessEnabled属性标识您的请求是否指定了回调方法,并将响应写回到流中。

NOTE: Test the url from your browser to see if you get a successful response as its a WebGet method 注意:从您的浏览器测试URL,以查看您是否以WebGet方法获得成功的响应

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM