The most elegant solution I know implements an Attribute that allows you to accept the request depending on the Action or Controller named. I do not recommend registering the Attribute globally.
1. Create a new Attribute
public class AllowCrossSiteAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
base.OnActionExecuting(filterContext);
}
}
2. Register Action with Attribute
[AllowCrossSite]
public ActionResult Index()
{
return View();
}
3. Install CorsProxy.AspNet
for backward compatibility with IE
Install-Package CorsProxy.AspNet
3.1. Route configuration with CorsProxy
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Coloque antes da rota padrão.
routes.EnableCorsProxy();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
3.2. Configuring Bundles with CorsProxy
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js",
// Coloque os demais scripts relativos ao jQuery aqui
"~/Scripts/jquery-corsproxy-{version}.js"));
...
}
}
3.3. Implement a Handler for CORS requests
public class CorsProxyHttpHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
var url = context.Request.Headers["X-CorsProxy-Url"];
if (url == null)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription =
"X-CorsProxy-Url was not specified. The corsproxy should only be invoked from the proxy JavaScript.";
context.Response.End();
return;
}
try
{
var request = WebRequest.CreateHttp(url);
context.Request.CopyHeadersTo(request);
request.Method = context.Request.HttpMethod;
request.ContentType = context.Request.ContentType;
request.UserAgent = context.Request.UserAgent;
if (context.Request.AcceptTypes != null)
request.Accept = string.Join(";", context.Request.AcceptTypes);
if (context.Request.UrlReferrer != null)
request.Referer = context.Request.UrlReferrer.ToString();
if (!context.Request.HttpMethod.Equals("GET", StringComparison.OrdinalIgnoreCase))
context.Request.InputStream.CopyTo(request.GetRequestStream());
var response = (HttpWebResponse)request.GetResponse();
response.CopyHeadersTo(context.Response);
context.Response.ContentType = response.ContentType;
context.Response.StatusCode =(int) response.StatusCode;
context.Response.StatusDescription = response.StatusDescription;
var stream = response.GetResponseStream();
if (stream != null && response.ContentLength > 0)
{
stream.CopyTo(context.Response.OutputStream);
stream.Flush();
}
}
catch (WebException exception)
{
context.Response.AddHeader("X-CorsProxy-InternalFailure", "false");
var response = exception.Response as HttpWebResponse;
if (response != null)
{
context.Response.StatusCode = (int)response.StatusCode;
context.Response.StatusDescription = response.StatusDescription;
response.CopyHeadersTo(context.Response);
var stream = response.GetResponseStream();
if (stream != null)
stream.CopyTo(context.Response.OutputStream);
return;
}
context.Response.StatusCode = 501;
context.Response.StatusDescription = exception.Status.ToString();
var msg = Encoding.ASCII.GetBytes(exception.Message);
context.Response.OutputStream.Write(msg, 0, msg.Length);
context.Response.Close();
}
catch (Exception exception)
{
context.Response.StatusCode = 501;
context.Response.StatusDescription = "Failed to call proxied url.";
context.Response.AddHeader("X-CorsProxy-InternalFailure", "true");
var msg = Encoding.ASCII.GetBytes(exception.Message);
context.Response.OutputStream.Write(msg, 0, msg.Length);
context.Response.Close();
}
}
public bool IsReusable { get { return true; }}
}
3.4. Setting up the Ajax call
Before your .load
, configure jQuery with the following:
$.ajaxPrefilter(function (options, originalOptions, jqXhr) {
if (!window.CorsProxyUrl) {
window.CorsProxyUrl = '/corsproxy/';
}
// only proxy those requests
// that are marked as crossDomain requests.
if (!options.crossDomain) {
return;
}
if (getIeVersion() && getIeVersion() < 10) {
var url = options.url;
options.beforeSend = function (request) {
request.setRequestHeader("X-CorsProxy-Url", url);
};
options.url = window.CorsProxyUrl;
options.crossDomain = false;
}
});
The original explanation is here .