2016-03-28 18 views
17

Ho cercato accuratamente ma non riesco a trovare una soluzione a questo problema nella mia circostanza particolare.CORS abilitato ma la risposta per il preflight ha un codice di stato HTTP 404 non valido quando POSTing JSON

Le chiamate di servizio tra domini tramite Fiddler (POST) vengono eseguite correttamente e i dati vengono ricevuti. Tuttavia, tramite il browser (Chrome) viene visualizzato il messaggio 'preflight ha codice di stato HTTP non valido 404'

Ho un'applicazione Web API e ho installato CORS e ho assicurato quanto segue nel file web.config:

<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> 

Ecco la chiamata Ajax:

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); 
     } 
    }); 

Ovviamente, funziona sullo stesso dominio perfettamente e, come detto, funziona utilizzando Fiddler.

Sono certo che è il preflight del browser OPZIONI controllare che non funzioni per il tipo di contenuto di 'application/json' ma non sono sicuro di come risolverlo.

C'è qualcosa che manca nel file web.config che dovrei aggiungere?

Ho provato a rimuovere "content-type" senza alcun effetto.

Avevo sperato this article avrebbe risolto il problema (sembrava promettente), ma si verifica lo stesso errore:

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

risposta

14

finalmente ho potuto far funzionare tutto questo.

Questo articolo 'WebAPI with CORS – IIS Intercepts OPTIONS Verb' ha informato il mio pensiero. Un'immagine mostrava dove, in IIS, appariva la mappatura del gestore OPTIONS e perché, all'interno di web.config, era necessario rimuoverlo per assicurarsi che IIS non lo intercettasse.

Quando ho dato un'occhiata a IIS che il gestore NON ERA lì. Poi ho dato un'occhiata all'articolo collegato 'Can't set HttpHandler order using Web.Config unless a «clear» tag exists' e ho visto che, in questo articolo, dopo aver rimosso il gestore OPTION, è stato quindi aggiunto esplicitamente all'interno di web.config.

Come non ho potuto vedere il gestore OPTION in IIS, anch'io l'ho aggiunto al file web.config e tutto ha funzionato all'improvviso. Sembrava che questa aggiunta fosse ciò che era necessario.

La sezione relativa ai gestori di web.config si presenta come segue (avviso ho deciso di mantenere la "rimozione" iniziale nel caso in cui ciò abbia causato problemi se avessi effettuato la migrazione su un server Web diverso in futuro).

<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> 
+0

funziona anche per me .. –

+0

la prego di aiutarmi su questo: https://magento.stackexchange.com/questions/170342/ magento-htaccess-response-for-preflight-has-invalid-http-status-code-400 –

+0

Grazie ha funzionato. È importante aggiungere anche i gestori. – Dileep

34

Grazie ma errore 405, dopo la configurazione di cui sopra cambia.

Finalmente funziona dopo l'aggiunta di seguito il codice in Web API file 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(); 
     } 
    } 
+1

perché questa non è ancora una risposta? – Immortal

2

Ho una configurazione simile che stava mostrando errori 404 e 500 errori come stavo cercando di ottenere CORS in esecuzione sul mio servizio web . Fondamentalmente la mia soluzione utilizzava la soluzione di Hussain, ma mentre ripulivo la mia correzione, notai che era necessaria solo una linea di risposta, e che ero in grado di mantenere i gestori web originali nel web.config, e NON dovevo spostare tutto il gestori di risposta nel codice.

Fondamentalmente, il mio correzione include questa Uno dei principali FIX nel mio gestore ApplicationOnBeginRequest:

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

e questi gestori nel mio 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> 

Mi dispiace non poteva inviare questa si noti come un commento alla risposta di Hussain.

9

Questo ha funzionato per me.

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(); 
    } 
} 

Nel 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> 

ricostruire e oplà.

0

Per asp core utilizzare questo codice in Startup.cs nella procedura Configure. Ho usato per la versione 2.0, ma penso che dovrebbe funzionare con più anziani troppo

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