2011-07-05 6 views
4

フォームポストを受け入れ、CORSリクエストのサポートを追加するサービスを維持しています。Firefox 3.6で問題を見つけ、OPTIONSリクエストヘッダーでプリフライトリクエストを送信しました。aspxページのOPTIONSリクエストヘッダーをサポートします

一般的なhttpハンドラページで必要なAccess-Control-Allow-Origin応答ヘッダーを追加するのに問題はありませんでしたが、完全に壊れたaspxページでは問題があります。間違いなくPage_Loadに当たっていないので、ページのライフサイクルのどこに止まっているのか分かりません。

誰もが考えている?

ありがとうございます!あなたは、私がこれのいくつかは、どこかの記事から来たと思うし、それの他の部分は、家の中で開発されたHttpModuleHttpHandler

でこれを行うことができます

+0

ウェブサービスにページロードイベントがないため、何を意味するのか不明です。通常、Webサービスはwebmethod属性を持つ単一の関数です。 http://msdn.microsoft.com/en-us/library/system.web.services.webservice.aspx – Hogan

+1

「サービス」を混乱させてご利用いただきありがとうございます。それは、POSTを受け付けるページを持つウェブサイトです。私はそれがaspxのページである必要はないことを理解しますが、それは簡単に変更することができないように既にそれにリンクしている野生のページがあります。 – ari

答えて

9

...ので、それのいくつかは、どこか別の場所から来た場合には

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace YourNamespaceHere 
{ 
    using System; 
    using System.Web; 
    using System.Collections; 

    public class CrossOriginModule : IHttpModule { 
     public String ModuleName { 
      get { return "CrossOriginModule"; } 
     }  

     public void Init(HttpApplication application) { 
      application.BeginRequest += (new EventHandler(this.Application_BeginRequest)); 
     } 

     private void Application_BeginRequest(Object source, EventArgs e) { 
      HttpApplication application = (HttpApplication)source; 
      HttpContext context = application.Context; 
      CrossOriginHandler.SetAllowCrossSiteRequestOrigin(context); 
     } 

     public void Dispose() 
     { 
     } 
    } 

    public class CrossOriginHandler : IHttpHandler 
    { 
     #region IHttpHandler Members 
     public bool IsReusable 
     { 
      get { return true; } 
     } 

     public void ProcessRequest(HttpContext context) 
     { 
      //Clear the response (just in case) 
      ClearResponse(context); 

      //Checking the method 
      switch (context.Request.HttpMethod.ToUpper()) 
      { 
       //Cross-Origin preflight request 
       case "OPTIONS": 
        //Set allowed method and headers 
        SetAllowCrossSiteRequestHeaders(context); 
        //Set allowed origin 
        //This happens for us with our module: 
        SetAllowCrossSiteRequestOrigin(context); 
        //End 
        context.Response.End(); 
        break; 

       default: 
        context.Response.Headers.Add("Allow", "OPTIONS"); 
        context.Response.StatusCode = 405; 
        break; 
      } 

      context.ApplicationInstance.CompleteRequest(); 
     } 
     #endregion 

     #region Methods 
     protected void ClearResponse(HttpContext context) 
     { 
      context.Response.ClearHeaders(); 
      context.Response.ClearContent(); 
      context.Response.Clear(); 
     } 

     protected void SetNoCacheHeaders(HttpContext context) 
     { 
      context.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1)); 
      context.Response.Cache.SetValidUntilExpires(false); 
      context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); 
      context.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
      context.Response.Cache.SetNoStore(); 
     } 
     #endregion 

     public static void SetAllowCrossSiteRequestHeaders(HttpContext context) 
     { 
      string requestMethod = context.Request.Headers["Access-Control-Request-Method"]; 

      context.Response.AppendHeader("Access-Control-Allow-Methods", "GET,POST"); 

      //We allow any custom headers 
      string requestHeaders = context.Request.Headers["Access-Control-Request-Headers"]; 
      if (!String.IsNullOrEmpty(requestHeaders)) 
       context.Response.AppendHeader("Access-Control-Allow-Headers", requestHeaders); 
     } 

     public static void SetAllowCrossSiteRequestOrigin(HttpContext context) 
     { 
      string origin = context.Request.Headers["Origin"]; 
      if (!String.IsNullOrEmpty(origin)) 
       context.Response.AppendHeader("Access-Control-Allow-Origin", origin); 
      else 
       //This is necessary for Chrome/Safari actual request 
       context.Response.AppendHeader("Access-Control-Allow-Origin", "*"); 
     } 
    } 
} 

そして、Web.configファイルで:

... 
    <system.webServer> 
    ... 
    <modules runAllManagedModulesForAllRequests="true"> 
    ... 
      <add name="CrossOriginModule" preCondition="managedHandler" type="YOURNANMESPACEHERE.CrossOriginModule, ASSEMBLYNAME" /> 
    </modules> 
    <handlers> 
      <add name="CrossOrigin" verb="OPTIONS" path="*" type="YOURNAMESPACEHERE.CrossOriginHandler, ASSEMBLYNAME" /> 
    </handlers> 
    </system.webServer> 
4

スティーブの回答私、私が原因クレジットを与えていないため、事前に謝罪しますそれは必然的に私の場合の解決につながりました。それが私がそれに投票した理由です。しかし、HttpHandlerは明示的に必要ではないようです。だから私はCORSを厳密にリクエストパイプラインに接続するモジュール自体に組み込んだ。私のコード:

using System; 
using System.Web; 

namespace NAMESPACE.HttpModules 
{ 
    public class CrossOriginModule : IHttpModule 
    { 
     public String ModuleName 
     { 
      get { return "CrossOriginModule"; } 
     } 

     public void Init(HttpApplication application) 
     { 
      application.BeginRequest += (new EventHandler(this.Application_BeginRequest)); 
     } 

     private void Application_BeginRequest(Object source, EventArgs e) 
     { 
      HttpApplication application = (HttpApplication)source; 
      HttpContext context = application.Context; 

      string httpMethod = context.Request.HttpMethod.ToUpper(); 

      //preflight 
      if (httpMethod == "OPTIONS") 
      { 
       ClearResponse(context); 

       //Set allowed method and headers 
       SetAllowCrossSiteRequestHeaders(context); 
       //Set allowed origin 
       SetAllowCrossSiteRequestOrigin(context); 

       //end request 
       context.ApplicationInstance.CompleteRequest(); 
      } 
      else 
      { 
       SetAllowCrossSiteRequestOrigin(context); 
      } 

     } 
     static void SetAllowCrossSiteRequestHeaders(HttpContext context) 
     { 
      string requestMethod = context.Request.Headers["Access-Control-Request-Method"]; 

      context.Response.AppendHeader("Access-Control-Allow-Methods", "GET,POST"); 

      //We allow any custom headers 
      string requestHeaders = context.Request.Headers["Access-Control-Request-Headers"]; 
      if (!String.IsNullOrEmpty(requestHeaders)) 
       context.Response.AppendHeader("Access-Control-Allow-Headers", requestHeaders); 

      //allow credentials 
      context.Response.AppendHeader("Access-Control-Allow-Credentials", "true"); 
     } 

     static void SetAllowCrossSiteRequestOrigin(HttpContext context) 
     { 
      string origin = context.Request.Headers["Origin"]; 
      if (!String.IsNullOrEmpty(origin)) 
       context.Response.AppendHeader("Access-Control-Allow-Origin", origin); 
      else 
       context.Response.AppendHeader("Access-Control-Allow-Origin", "*"); 
     } 

     static void ClearResponse(HttpContext context) 
     { 
      context.Response.ClearHeaders(); 
      context.Response.ClearContent(); 
      context.Response.Clear(); 
     } 

     public void Dispose() 
     { 
     } 
    } 

} 

そして、あなたのweb.config

<modules runAllManagedModulesForAllRequests="true"> 
    <add name="CrossOriginModule" preCondition="managedHandler" type="NAMESPACE.HttpModules.CrossOriginModule" /> 
</modules> 

にこれは、必要に応じてレスポンスヘッダを設定し、それは通常どおりMVCは要求を処理できるようになります。