【问题标题】:OPTIONS preflight request getting 400 bad request on httpsOPTIONS 预检请求在 https 上收到 400 个错误请求
【发布时间】:2019-10-03 07:15:00
【问题描述】:

我在前端有 Ajax 调用,我正在通过 ajax 调用调用 WCF 服务,但是 ajax 调用有一些添加标头,这就是为什么第一次预检 OPTIONS 请求被引发并且由于“url”而下降的原因已被 cors 政策阻止。

我已经在我的 web.config 文件中添加了下面的代码,但它仍然可以工作。

<system.webServer>
        <security>
            <requestFiltering>
                <verbs>
                    <add verb="OPTIONS" allowed="true" />
                    <add verb="POST" allowed="true" />
                    <add verb="GET" allowed="true" />
                    <add verb="DELETE" allowed="false" />
                </verbs>
            </requestFiltering>
        </security>
        <httpProtocol>
            <customHeaders>
                <remove name="X-Powered-By" />
                <add name="Access-Control-Allow-Credentials" value="true" />
                <add name="Access-Control-Allow-Origin" value="*" />
                <add name="Access-Control-Allow-Methods" value="GET,POST,DELETE,OPTIONS" />
                <add name="Access-Control-Allow-Headers" value="accept, cache-control, content-type, authorization, context" />
            </customHeaders>
        </httpProtocol>
    </system.webServer>


$.ajax({
                async: true,
                type: "POST",
                headers: {
                    'Authorization': 'Basic ' + btoa(BasicAuth),
                    'Context': 'Context' + btoa(ContextHeader)
                },
                contentType: "application/json; charset=utf-8",
                data: '{"Id": "' + Id + '" }',
                url: URL + "/MethodName",
                success: function (result) {
                    response = result;
                    if (response == true)
                        Xrm.Page.data.refresh(true);
                    $('#msgDiv').fadeOut('slow');
                },
                error: function (status) {
                    console.log(status.status);
                    $('#msgDiv').fadeOut('slow');
                    Configurations.OnFailure(status);
                }
            });

上面是我用javascript写的代码。

在 HTTP 上调用它工作正常。但在 HTTPS 上调用它不工作。

我在控制台上收到如下错误

enter code here

【问题讨论】:

  • “下面的代码”中没有任何内容,您应该将它放在问题中 - 但您似乎还没有配置 IIS 来处理 OPTIONS 请求
  • 我已经检查了 iis 以处理选项请求
  • 我可以看到请求过滤中允许的 OPTIONS 动词。
  • 是的,但是您没有显示的代码(服务器端代码)显然并未真正处理 OPTIONS 请求(只是因为 IIS 允许它,并没有使其 处理 i>)
  • 您能否通过使用 PostMan Tool over Https 获得正确的响应?此外,我将以下代码添加到 global.asax 文件的 Application_beginrequest 事件中。 if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS") { Response.End(); }

标签: javascript c# ajax wcf


【解决方案1】:

这是我的 CORS 解决方案,希望对您有用。将全局应用程序类添加到我的 wcf 服务应用程序。
Global.asax

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("Cache-Control", "no-cache");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With,Accept");
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
                HttpContext.Current.Response.End();
            }
        }

服务器上的 web.config

  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="mybinding">
          <security mode="Transport">
            <transport clientCredentialType="Basic" proxyCredentialType="Basic"></transport>
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior>
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
    </serviceHostingEnvironment>
    <protocolMapping>
      <add scheme="https" binding="webHttpBinding" bindingConfiguration="mybinding"/>
      <add scheme="http" binding="webHttpBinding" />
    </protocolMapping>
  </system.serviceModel>

然后在客户端(我们运行JS的地方)安装服务器服务证书。

JS.

<script>
        function make_base_auth(user, password) {
            var tok = user + ':' + password;
            var hash = window.btoa(tok); //javascript built-in function
            return "Basic " + hash;
        }
        $(function () {
            $.ajax({
                type: "GET",
                url: "https://vabqia130vm:12001/service1.svc/getdata?value=34",
                contentType: "application/json;charset=utf-8",
                beforeSend: function (req) {
                    req.setRequestHeader("Authorization", make_base_auth("administrator",
                        "abcde12345!"));
                },
                success: function (d) {
                    console.log(d);
                },

            });

        })
    </script>

结果。

如果有什么可以帮助的,请随时告诉我。

【讨论】:

    【解决方案2】:

    我在服务端创建了 dispatchmessageInspector 来在调用实际服务之前检查身份验证是否正确。

    以下代码是我为处理调度检查员的身份验证而编写的。

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
            {
                var logFileName = SetLogInfo("JavaScriptBasicAuth");
                try
                {
                    if (!HttpContext.Current.Request.HttpMethod.Equals("OPTIONS"))
                    {
                        var basicAuth = HttpContext.Current.Request.Headers["Authorization"];
                        if (basicAuth != null)
                        {
                            string[] separator = basicAuth.Split(' ');
                            BasicAuthenticationBehaviorAttribute basicauth = new BasicAuthenticationBehaviorAttribute();
                            if (!basicauth.ValidateBasicAuth(separator[1]))
                            {
                                throw new WebFaultException(HttpStatusCode.Unauthorized);
                            }
                        }
                        else
                        {
                            FileLogger.LogError("401 (Unauthorized) Error - " + "You are not authorized to perform this operation. Please contact administrator.", LOG_SUB_DIRECTORY, logFileName);
                            throw new WebFaultException(HttpStatusCode.Unauthorized);
                        }
                }
            }
    

    但调用在 Dispatcher 检查器代码之前失败。

    【讨论】:

    • 你为什么要写一个非答案来回答你自己的问题?
    猜你喜欢
    • 2015-10-20
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多