CORS(跨源资源共享)https不工作(IIS承载的WCF已启用rest的终结点)



嗨,希望有人能帮助

我一直在寻找一个简单的原型,通过https使用CORS到WCF。我们已经实现了一个解决方案,并在http中进行了测试,它运行良好。一旦我们尝试使用https调用WCF端点,在这种情况下我们就会得到一个"404未找到"。但在我们的生产代码中,我收到了一个"400坏请求",我稍后会发布!现在我想帮助解决404错误。

我已经搜索并尝试了很多东西,但仍然没有成功!

我写了一个小的测试web项目和WCF端点,在http中运行良好。

在客户端,我向以下端点发出jquery ajax请求

var theUrl = "https://myhostmachine/Cors/service.svc/web";
function makeGetDataJQueryRequest() {
    $.support.cors = true;
    $.ajax({
        url: theUrl + "/GetData?value=24",
        contentType: "application/json; charset=utf-8",
        type: "POST",
        cache: false,
        dataType: "json",
        //                data: undefined,
        success: function (response) {
            alert("success");
        },
        error: function (a, b, c) {
            alert("error");
        }
    });
}

在服务器上,我有我的WCF代码,它完成了所有的飞行前cors响应,正如我所说的,在http中工作。

  1. 我已经设置了一个自签名证书,并在我的IIS中使用了它,还确保通过mmc插件将其添加到我的证书存储中。

  2. 当我直接提出请求时,我可以看到它没有发送OPTIONS请求,为什么不呢?但它确实是通过http发送的?

小提琴手请求:

POST https://myhostmachine/Cors/service.svc/web/GetData?value=24 HTTP/1.1
Host: hsw10530.cse-servelec.com
Connection: keep-alive
Content-Length: 0
Accept: application/json, text/javascript, */*; q=0.01
Origin: https://myhostmachine
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.103 Safari/537.36
Content-Type: application/json; charset=utf-8
Referer: https://hsw10530.cse-servelec.com/CorsClient/
Accept-Encoding: gzip,deflate
Accept-Language: en-US,en;q=0.8
Cookie: ASPSESSIONIDCGCSARDQ=IFNPFPKAJIMFCJHEANDFOBCH

响应:

HTTP/1.1 404 Not Found
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Thu, 11 Sep 2014 09:36:51 GMT
Content-Length: 0

Web.config如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

  <system.web>
    <compilation debug="true" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True" />
          <serviceDebug includeExceptionDetailInFaults="True" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="restBehaviour">
          <webHttp />
          <CorsSupport />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <extensions>
      <behaviorExtensions>
        <add name="CorsSupport" type="WcfService.Cors.CorsSupportBehaviorElement, WcfService" />
      </behaviorExtensions>
    </extensions>
    <bindings>
      <webHttpBinding>
        <binding name="CORSWebHttpBinding" crossDomainScriptAccessEnabled="True" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647">
          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <security mode="Transport">
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
    <services>
      <service name="WcfService.Service1">
        <host>
          <baseAddresses />
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="WcfService.IService1" />
        <endpoint address="web" binding="webHttpBinding" bindingConfiguration="" behaviorConfiguration="restBehaviour" contract="WcfService.IService1" />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

以下是WCF代码,或者至少是完成所有飞行前cors内容的重要部分。

public class CorsMessageInspector : IDispatchMessageInspector
    {
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            HttpRequestMessageProperty httpRequest = request.Properties["httpRequest"] as HttpRequestMessageProperty;
            // Check if the client sent an "OPTIONS" request
            if (httpRequest != null)
            {
                if (httpRequest.Method == "OPTIONS")
                {
                    // Store the requested headers
                    OperationContext.Current.Extensions.Add(new PreflightDetected(
                        httpRequest.Headers["Access-Control-Request-Headers"]));
                }
            }
            return null;
        }
        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            HttpResponseMessageProperty property = null;
            if (reply == null)
            {
                // This will usually be for a preflight response
                reply = Message.CreateMessage(MessageVersion.None, null);
                property = new HttpResponseMessageProperty();
                reply.Properties[HttpResponseMessageProperty.Name] = property;
                property.StatusCode = HttpStatusCode.OK;
            }
            else
            {
                property = reply.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty;
            }
            PreflightDetected preflightRequest = OperationContext.Current.Extensions.Find<PreflightDetected>();
            if (preflightRequest != null)
            {
                // Add allow HTTP headers to respond to the preflight request
                if (preflightRequest.RequestedHeaders == string.Empty)
                    property.Headers.Add("Access-Control-Allow-Headers", "Accept");
                else
                    property.Headers.Add("Access-Control-Allow-Headers", preflightRequest.RequestedHeaders + ", Accept");
                //http://hsw10530.cse-servelec.com
                property.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            }
            // Add allow-origin header to each response message, because client expects it
            property.Headers.Add("Access-Control-Allow-Origin", "*");
        }
    }

如果您曾经能够通过ssl设置CORS,那么我们将非常感谢您的帮助,您做了什么使其工作?

非常感谢Andrew

好的,我开始工作了,毕竟我只需要提供bindingConfiguration作为我在配置底部的端点,它是一个空字符串

所以配置文件中确实包含了它;我只是没有具体说明。您还可以看到,安全模式是Transportforssl,否则在标准http上,应该将其设置为None。

<endpoint address="web" binding="webHttpBinding" bindingConfiguration="CORSWebHttpBinding" behaviorConfiguration="restBehaviour" contract="WcfService.IService1" />

我也不需要CORSWebHttpBinding上的crossDomainScriptAccessEnabled="True",因为这似乎可以在使用http时阻止它,但在https上可以。

最新更新