webentwicklung-frage-antwort-db.com.de

CORS ist aktiviert, aber die Antwort auf Preflight hat einen ungültigen HTTP-Statuscode 404 beim POST von JSON

Ich habe gründlich gesucht, kann aber unter meinen Umständen keine Lösung für dieses Problem finden.

Domainübergreifende Serviceaufrufe, die Fiddler (POST) verwenden, werden ordnungsgemäß ausgeführt und die Daten werden empfangen. Durch den Browser (Chrome) erhalte ich jedoch die Nachricht "Preflight hat ungültigen HTTP-Statuscode 404".

Ich habe eine Web-API-Anwendung und habe CORS installiert und sichergestellt, dass Folgendes in der Datei web.config vorhanden ist:

<system.webServer>
    <handlers>
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
      </customHeaders>
    </httpProtocol>
</system.webServer>

Hier ist der Ajax-Aufruf: 

var secretKey = 'difusod7899sdfiertwe08wepifdfsodifyosey',
    url = 'http://api.intrinsic.co.uk/api/v1/PTS/ActiveDrivers?api_key=098werolllfWnCbPGAuIXVOJidDHRfYcgxImMlxTXopuekXrSOqOWzEAIdeNTWGPQPpyHxgVGsFysGFKPzq';

  jQuery.ajax ({
      url: url,
      type: "POST",
      data: JSON.stringify({ secretKey: secretKey}),
      dataType: "json",
      contentType: "application/json; charset=utf-8",
      success: function(data){
          var content = "<table class=\"container\"><thead><tr><th>Driver Number</th><th>Timestamp</th><th>VRN</th><th>Latitude</th><th>Longitude</th><th>Track Link</th></tr></thead><tbody>";
          $.each(data.ActiveDrivers.DriverLocationStatus, function (index, element) {
              content += "<tr><td>" + element.DriverNumber + "</td>";
              content += "<td>" + dateFormat(element.Timestamp, "d/m/yy") + " " + dateFormat(element.Timestamp, "h:MM TT") + "</td>";
              content += "<td>" + element.VRN + "</td>";
              content += "<td>" + element.CurrentLatitude + "</td>";
              content += "<td>" + element.CurrentLongitude + "</td>";
              content += "<td><a href=\"https://www.google.co.uk/maps/place//@" + element.CurrentLatitude + "," + element.CurrentLongitude + ",15z/\" target='_blank'>Track &raquo;</a></td></tr>";
          });
          content += "</tbody></table>";
          $( "#result" ).html( content );
      }
  });

Natürlich funktioniert es perfekt auf derselben Domain und wie erwähnt mit Fiddler.

Ich bin sicher, dass die Preflight-OPTIONS-Prüfung des Browsers für den Inhaltstyp 'application/json' fehlschlägt.

Gibt es etwas in der Datei web.config, das ich hinzufügen sollte?

Ich habe versucht, 'content-type' ohne Auswirkung zu entfernen.

Ich hatte gehofft, dass dieser Artikel das Problem lösen würde (es schien vielversprechend), aber der gleiche Fehler ist aufgetreten

XMLHttpRequest cannot load [URL]. Response for preflight has invalid HTTP status code 404
21
ChrisCurrie

Danke aber 405 Fehler bekommen, nachdem die obigen Konfigurationsänderungen vorgenommen wurden.

Nach dem Hinzufügen von Code in der Datei "web api Global.asax" funktioniert es schließlich

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

Ich habe es endlich geschafft.

Dieser Artikel ' WebAPI with CORS - IIS fängt OPTIONEN Verb ab "hat mein Denken bestätigt. Ein Bild zeigte, wo in IIS das OPTIONS-Handler-Mapping erschien und warum es in der web.config entfernt werden musste, um sicherzustellen, dass IIS nicht abgefangen wurde.

Als ich IIS sah, war dieser Handler NICHT da. Dann habe ich einen Blick auf den verknüpften Artikel ' HttpHandler-Reihenfolge mit Web.Config setzen können, es sei denn, es existiert ein "clear" -Tag '. In diesem Artikel wurde festgestellt, dass der OPTION-Handler nach dem Entfernen explizit war innerhalb der web.config hinzugefügt.

Da ich den OPTION-Handler in IIS nicht sehen konnte, fügte ich ihn auch der Datei web.config hinzu und alles funktionierte plötzlich. Es schien, dass dieser Zusatz notwendig war.

Der letzte Abschnitt der web.config-Handler sieht wie folgt aus (Hinweis: Ich habe mich dazu entschlossen, das anfängliche 'remove' beizubehalten, nur falls dies zu Problemen führte, wenn ich in der Zukunft zu einem anderen Webserver migrierte).

<system.webServer>
    <handlers>
      <remove name="WebDAV"/>
      <remove name="OPTIONSVerbHandler"/>
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
      <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" responseBufferLimit="4194304" />
    </handlers>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS" />
      </customHeaders>
    </httpProtocol>
</system.webServer>
15
ChrisCurrie

Das hat bei mir funktioniert.

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

In Web.config

    <httpProtocol>
        <customHeaders>

    <add name="Access-Control-Allow-Origin" value="*"/>
    <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS"/>
    <add name="Access-Control-Allow-Headers" value="Content-Type"/>
        </customHeaders>
    </httpProtocol>

wiederaufbau und Hey Presto.

11
Darren Street

Ich habe ein ähnliches Setup, bei dem 404 Fehler und 500 Fehler angezeigt wurden, als ich versuchte, CORS für meinen Webdienst auszuführen. Mein Fix verwendete im Wesentlichen die Lösung von Hussain, aber als ich meinen Fix bereinigte, bemerkte ich, dass nur eine Response-Zeile erforderlich war, und ich konnte die ursprünglichen Webhandler in der web.config beibehalten und brauchte KEINEN ganzen Code zu verschieben Antworthandler in den Code.

Grundsätzlich beinhaltet mein Fix diesen ONE MAJOR FIX in meinem ApplicationOnBeginRequest-Handler:

    private void ApplicationOnBeginRequest( object sender, EventArgs eventArgs )
        {
...
            if ( context.Request.HttpMethod == "OPTIONS" )
                response.End();
        }

und diese Handler in meiner web.config:

<system.webServer>
    <!--Other handlers/modules ...-->
    <httpProtocol>
        <customHeaders>
            <clear />
            <add name="Access-Control-Allow-Origin" value="*" />
            <add name="Access-Control-Allow-Credentials" value="true" />
            <add name="Access-Control-Allow-Headers" value="Content-Type,Accept" />
            <add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
        </customHeaders>
    </httpProtocol>
   </system.webServer>

Entschuldigung, ich konnte diese Notiz nicht als Kommentar zu Hussains Antwort senden.

2
InquisitionX

Verwenden Sie diesen Code für asp core in Startup.cs in der Prozedur Configure. Ich habe für Version 2.0 verwendet, aber ich denke, es sollte auch mit älter funktionieren

app.UseCors(builder => {
                builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
            });
0
valentasm

Das hat mir auch geholfen, ich hatte CORS bereits in der web.config konfiguriert

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