Подтвердить что ты не робот

CORS включен, но ответ для предполета имеет недопустимый код статуса HTTP 404, когда POSTING JSON

Я тщательно искал, но не могу найти решение этой проблемы в моих конкретных обстоятельствах.

Службы междоменной службы с использованием Fiddler (POST) выполняются правильно и данные принимаются. Однако через браузер (Chrome) я получаю сообщение "preflight имеет недопустимый код статуса HTTP 404"

У меня есть приложение Web API и установлено CORS, и в файле 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>

Вот вызов 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 );
      }
  });

Очевидно, что работает над одним и тем же доменом и, как уже упоминалось, работает с использованием Fiddler.

Я уверен, что проверка опций OPTIONS перед браузером не соответствует типу содержимого 'application/json', но я не уверен, как это исправить.

Есть ли что-то в файле web.config, который я должен добавить?

Я попытался удалить 'content-type' без каких-либо изменений.

Я надеялся, что эта статья решит проблему (она кажется многообещающей), но такая же ошибка встречается:

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

Ответ 1

Спасибо, но получив ошибку 405 после изменения указанной конфигурации.

Наконец, он работает после добавления ниже кода в файле web api 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();
        }
    }

Ответ 2

Я, наконец, получил это, чтобы работать.

Эта статья WebAPI с CORS - IIS перехватывает OPTIONS Verb, - сообщил мой взгляд. Изображение показало, где в IIS появилось отображение обработчика OPTIONS и почему в web.config нам нужно было удалить его, чтобы IIS не перехватил.

Когда я взглянул на IIS, обработчик НЕ БЫЛ. Затем я взглянул на связанную статью Невозможно установить порядок HttpHandler с использованием Web.Config, если не существует тега "clear" и увидел, что в этой статье, после удаления обработчика OPTION он был явно добавлен в файл web.config.

Поскольку я не мог видеть обработчик OPTION в IIS, я тоже добавил его в файл web.config, и все неожиданно работало. Оказалось, что это дополнение необходимо.

Последний раздел обработчиков web.config выглядит следующим образом (извещение я решил сохранить исходный "удалить" на всякий случай, если это вызвало проблемы, если в будущем я перенесюсь на другой веб-сервер).

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

Ответ 3

Это сработало для меня.

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

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

перестройте и эй престо.

Ответ 4

У меня есть аналогичная настройка, которая показывала 404 ошибки и 500 ошибок, поскольку я пытался запустить CORS на моем веб-сервисе. Мое исправление в основном использовало решение Hussain, но когда я очистил свое исправление, я заметил, что нужна только одна линия отклика, и я смог сохранить исходные обработчики веб-страниц в файле web.config и НЕ должен был переместить все обработчиков ответов в код.

В основном, мое исправление включает этот ОДИН MAJOR FIX в моем обработчике ApplicationOnBeginRequest:

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

и эти обработчики в моем 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>

Извините, я не смог отправить эту заметку в качестве комментария к ответу Хуссейна.

Ответ 5

Для ядра asp используйте этот код в Startup.cs в процедуре настройки. Я использовал для версии 2.0, но я думаю, что он должен работать со старыми тоже

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

Ответ 6

Это тоже помогло, у меня уже был CORS в web.config

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