Support for OPTIONS request header on aspx page

I support a service that accepts a form message and adds support for CORS requests. I ran into a problem in Firefox 3.6 where it sends a pre-check request with the OPTIONS request header.

I had no problem adding the required Access-Control-Allow-Origin response headers with the shared HTTP handler page, but I had difficulty with the full version of the aspx page. This definitely doesn't get into page_Load, and I can't figure out where on the page life cycle it is stuck.

Does anyone have any ideas?

Thanks!

+4
source share
2 answers

You can do it with HttpModule and HttpHandler

I think that some of them came from an article somewhere, and other parts were developed in the house ... therefore, if some of them came from somewhere else, I apologize in advance for not giving the proper loan:

 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", "*"); } } } 

And in 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> 
+9
source

Steve answered surprisingly, this inevitably led me to a resolution in my case, and that is why I voted for him. However, it seems to me that the HttpHandler may not be needed explicitly. Therefore, I configured CORS, strictly in the module itself, which connects to the request pipeline. My code is:

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

And in your web.config

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

This will allow you to customize response headers as needed, and let MVC process the request as usual.

+4
source

All Articles