web-dev-qa-db-ja.com

CORSは有効になっていますが、JSONをPOSTするときにプリフライトの応答に無効なHTTPステータスコード404が含まれています

私は徹底的に検索しましたが、私の特定の状況でこの問題の解決策を見つけることができません。

Fiddler(POST)を使用したクロスドメインサービスコールは正しく実行され、データが受信されます。ただし、ブラウザ(Chrome)から「プリフライトには無効な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を使用して動作します。

'application/json'のコンテンツタイプに対して失敗するのは、ブラウザーのプリフライトオプションチェックであると確信していますが、修正方法はわかりません。

Web.configファイルに何か追加する必要があるものがありませんか?

「content-type」を削除してみましたが、影響はありません。

この記事 が問題を解決することを望んでいました(有望なように見えました)が、同じエラーが発生します。

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

おかげで、上記の設定が変更された後、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();
        }
    }
38
Hussain

私はついにこれを機能させました。

この記事「 WebAPI with CORS – IIS Intercepts OPTIONS Verb 」は、私の考えを伝えました。画像は、IISでOPTIONSハンドラーマッピングが表示された場所とその理由を示し、web.config内でIISがインターセプトされないようにするためにそれを削除する必要がありました。

IISを見てみると、そのハンドラーはそこにありませんでした。次に、リンクされた記事「 "clear"タグが存在しない限り、Web.Configを使用してHttpHandlerの順序を設定できません 」を見て、この記事でOPTIONハンドラーを削除した後、その後、web.config内に明示的に追加されました。

IISでOPTIONハンドラーが表示されなかったため、それもweb.configファイルに追加しましたが、すべて突然動作しました。この追加が必要であるように見えました。

最後のweb.configハンドラーセクションは次のようになります(将来別のWebサーバーに移行した場合に問題が発生した場合に備えて、最初の「削除」を維持することにしました)。

<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

これは私のために働いた。

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>

再構築し、ちょっとプレスト。

11
Darren Street

WebサービスでCORSを実行しようとしたときに、404エラーと500エラーが表示されていた同様のセットアップがあります。私の修正は基本的にフセインのソリューションを使用していましたが、修正をクリーンアップしたときに、1行の応答行のみが必要であり、web.configに元のWebハンドラーを保持することができ、すべてを移動する必要はありませんでしたコードへの応答ハンドラー。

基本的に、私の修正にはこれが含まれていますONE 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>

フセインの回答へのコメントとしてこのメ​​モを送信できませんでした。

2
InquisitionX

ASPコアの場合は、構成手順のStartup.csでこのコードを使用します。私は2.0バージョンを使用しましたが、古いバージョンでも動作するはずです

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

これも助けてくれました。web.configで既にCORSを設定していました

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