具有跨域 Ajax 的 WCF Web 服务不起作用

Posted

技术标签:

【中文标题】具有跨域 Ajax 的 WCF Web 服务不起作用【英文标题】:WCF web service with CROSS Domian Ajax not working 【发布时间】:2018-04-12 11:29:45 【问题描述】:

使用 jsonp 调用 WCF Ajax 请求时出现错误 下面是我的 web.config

<?xml version="1.0"?>
<configuration>


  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="RestService.RestServiceImpl" behaviorConfiguration="ServiceBehaviour">
        <endpoint address="" binding="webHttpBinding" contract="RestService.IRestServiceImpl" behaviorConfiguration="web"></endpoint>
        <endpoint address="basic" binding="basicHttpBinding" name="HttpEndPoint" contract="RestService.IRestServiceImpl" ></endpoint>

        <endpoint
            address="Service1.svc"
            binding="mexHttpBinding"
            contract="IMetadataExchange"/>
      </service>
    </services>

    <behaviors>

      <serviceBehaviors>
        <behavior name="ServiceBehaviour">
          <!-- To avoid disclosing metadata information, set the value below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" />
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>

        </behavior>

      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <webHttpBinding>
        <binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true" />
      </webHttpBinding>
    </bindings>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>

还有我的界面

 using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    using System.Text;

    namespace RestService
    
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IRestServiceImpl" in both code and config file together.
        [ServiceContract]
        public interface IRestServiceImpl
        


            [WebInvoke(Method = "GET",
                ResponseFormat = WebMessageFormat.Json,
                BodyStyle = WebMessageBodyStyle.Wrapped,
                UriTemplate = "getallemp")]
            [return: MessageParameter(Name = "success")]
            string GetAllEmployee();




        
    

以下是我的服务类

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using WebService.DataLayer;

namespace RestService


    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "RestServiceImpl" in code, svc and config file together.
    // NOTE: In order to launch WCF Test Client for testing this service, please select RestServiceImpl.svc or RestServiceImpl.svc.cs at the Solution Explorer and start debugging.
    public class RestServiceImpl : IRestServiceImpl
    

        public string GetAllEmployee()
        
            cls_datalayer obj = new cls_datalayer();
            DataTable dt = obj.getDataTableFromQuery("select usercode from users where empstatus='A'");

            return ConvertDataTabletoString(dt);
        

        public string ConvertDataTabletoString(DataTable dt)
        
            System.Web.Script.Serialization.javascriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            serializer.MaxJsonLength = 50000000;
            List<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
            Dictionary<string, object> row;
            foreach (DataRow dr in dt.Rows)
            
                row = new Dictionary<string, object>();
                foreach (DataColumn col in dt.Columns)
                
                    row.Add(col.ColumnName, dr[col]);
                
                rows.Add(row);
            

            return serializer.Serialize(rows);
        




    

当我从浏览器调用它时,它会给出From Browser

但是当我使用跨域从 Ajax 请求中尝试这个时,我得到了错误

$.ajax(
                type: "GET",
                url: 'http://localhost:59672/RestServiceImpl.svc/getallemp',
                contentType: "application/json",
                dataType: "jsonp",
                cache: false,
                jsonpCallback: 'callback',
                success: function (data) 
                    alert();

                ,
                error: function (xhr) 
                    //console.log(xhr);
                    var err = eval("(" + xhr.responseText + ")");

                
            );

然后我收到错误请检查附件Attachment 01

Attachment 02

【问题讨论】:

【参考方案1】:

对我来说比 Web.config 版本更好:

创建Global.asax

将此代码添加到Global.asax.cs

protected 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");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
        HttpContext.Current.Response.End();
    

【讨论】:

以上是关于具有跨域 Ajax 的 WCF Web 服务不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何避免 jquery ajax 中使用 wcf 服务的跨域策略?

AJAX 跨域图像发布到 WCF 服务

跨域 jQuery Ajax 请求和 WCF REST 服务

经过身份验证的服务不支持跨域 javascript 回调。通过 SSL 代理对 WCF 服务的 AJAX 查询

Jsonp实现Ajax跨域Demo

我们可以在跨域中使用 Jquery $.ajax() 调用通过 https 访问 WCF 服务吗?