Настройка Access-Control-Allow-Origin в ASP.Net MVC - самый простой способ - PullRequest
198 голосов
/ 09 июня 2011

У меня есть простой метод действия, который возвращает JSON.Он работает на ajax.example.com.Мне нужно получить доступ к этому с другого сайта someothersite.com.

Если я попытаюсь позвонить, я получу ожидаемое ...:

Origin http://someothersite.com is not allowed by Access-Control-Allow-Origin.

Я знаю два способа обойтиэто: JSONP и создание пользовательского HttpHandler для установки заголовка.

Нет ли более простого способа?

Разве это невозможно для простогодействие, чтобы определить список разрешенных источников - или просто разрешить всем?Может быть, фильтр действий?

Оптимальным будет ...:

return json(mydata, JsonBehaviour.IDontCareWhoAccessesMe);

Ответы [ 12 ]

365 голосов
/ 09 июня 2011

Для простых контроллеров ASP.NET MVC

Создайте новый атрибут

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
        base.OnActionExecuting(filterContext);
    }
}

Отметьте свое действие:

[AllowCrossSiteJson]
public ActionResult YourMethod()
{
    return Json("Works better?");
}

Для ASP.NET Web API

using System;
using System.Web.Http.Filters;

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Response != null)
            actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");

        base.OnActionExecuted(actionExecutedContext);
    }
}

Пометить весь контроллер API:

[AllowCrossSiteJson]
public class ValuesController : ApiController
{

Или отдельные вызовы API:

[AllowCrossSiteJson]
public IEnumerable<PartViewModel> Get()
{
    ...
}

Для Internet Explorer <= v9 </h1> IE <= 9 не поддерживает CORS.Я написал javascript, который будет автоматически направлять эти запросы через прокси.Это все на 100% прозрачно (вам просто нужно включить мой прокси и скрипт). </p> Загрузите его, используя nuget corsproxy и следуйте инструкциям. Запись в блоге | Исходный код

116 голосов
/ 15 июля 2012

Если вы используете IIS 7+, вы можете поместить файл web.config в корень папки с этим в разделе system.webServer:

<httpProtocol>
   <customHeaders>
      <clear />
      <add name="Access-Control-Allow-Origin" value="*" />
   </customHeaders>
</httpProtocol>

См .: http://msdn.microsoft.com/en-us/library/ms178685.aspx И: http://enable -cors.org / # how-iis7

20 голосов
/ 07 сентября 2013

Я столкнулся с проблемой, когда браузер отказался обслуживать контент, который он извлек, когда запрос передавался в файлах cookie (например, xhr имел его withCredentials=true), а для сайта Access-Control-Allow-Origin было установлено * , (Ошибка в Chrome: «Невозможно использовать подстановочный знак в Access-Control-Allow-Origin, когда флаг учетных данных имеет значение true.»)

Основываясь на ответе @jgauffin, я создал его, который по сути является способом обхода этой конкретной проверки безопасности браузера, поэтому будьте осторожны с emptor.

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // We'd normally just use "*" for the allow-origin header, 
        // but Chrome (and perhaps others) won't allow you to use authentication if
        // the header is set to "*".
        // TODO: Check elsewhere to see if the origin is actually on the list of trusted domains.
        var ctx = filterContext.RequestContext.HttpContext;
        var origin = ctx.Request.Headers["Origin"];
        var allowOrigin = !string.IsNullOrWhiteSpace(origin) ? origin : "*";
        ctx.Response.AddHeader("Access-Control-Allow-Origin", allowOrigin);
        ctx.Response.AddHeader("Access-Control-Allow-Headers", "*");
        ctx.Response.AddHeader("Access-Control-Allow-Credentials", "true");
        base.OnActionExecuting(filterContext);
    }
}
14 голосов
/ 11 декабря 2015

Это действительно просто, просто добавьте это в web.config

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="http://localhost" />
      <add name="Access-Control-Allow-Headers" value="X-AspNet-Version,X-Powered-By,Date,Server,Accept,Accept-Encoding,Accept-Language,Cache-Control,Connection,Content-Length,Content-Type,Host,Origin,Pragma,Referer,User-Agent" />
      <add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, OPTIONS" />
      <add name="Access-Control-Max-Age" value="1000" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

В Origin поместите все домены, которые имеют доступ к вашему веб-серверу, в заголовки поместите все возможные заголовки, которые может использовать любой http-запрос ajax, в методы положите все методы, которые вы разрешаете на вашем сервере

regards :)

8 голосов
/ 12 апреля 2014

В WebAPI 2 теперь есть пакет для CORS, который можно установить с помощью: Install-Package Microsoft.AspNet.WebApi.Cors -pre -project WebServic

После этогоустановлен, следуйте этому для кода: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

8 голосов
/ 11 сентября 2013

Иногда глагол OPTIONS также вызывает проблемы

Просто: Обновите ваш web.config следующим

<system.webServer>
    <httpProtocol>
        <customHeaders>
          <add name="Access-Control-Allow-Origin" value="*" />
          <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

И обновите заголовки веб-службы / контроллера с помощью httpGet и httpOptions

// GET api/Master/Sync/?version=12121
        [HttpGet][HttpOptions]
        public dynamic Sync(string version) 
        {
3 голосов
/ 11 декабря 2015

Этот урок очень полезен.Чтобы получить краткую сводку:

  1. Используйте пакет CORS, доступный в Nuget: Install-Package Microsoft.AspNet.WebApi.Cors

  2. В своем файле WebApiConfig.cs добавьте config.EnableCors() к методу Register().

  3. Добавьте атрибут к контроллерам, который вам нужен для обработки коров:

[EnableCors(origins: "<origin address in here>", headers: "*", methods: "*")]

3 голосов
/ 04 мая 2015
    public ActionResult ActionName(string ReqParam1, string ReqParam2, string ReqParam3, string ReqParam4)
    {
        this.ControllerContext.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin","*");
         /*
                --Your code goes here --
         */
        return Json(new { ReturnData= "Data to be returned", Success=true }, JsonRequestBehavior.AllowGet);
    }
3 голосов
/ 14 марта 2014

Добавьте эту строку в ваш метод, если вы используете API.

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); 
1 голос
/ 11 октября 2018

Существуют различные способы передачи заголовков Access-Control-Expose-Headers.

  • Как пояснил jgauffin, мы можем создать новый атрибут.
  • Как пояснил LaundroMatt, мы можем добавить файл web.config.
  • Другой способ - добавить код, как показано ниже в файле webApiconfig.cs.

    config.EnableCors (новый EnableCorsAttribute ("", заголовки: "", методы: "*" ,posedHeaders: "TestHeaderToExpose") {SupportsCredentials = true});

Или мы можем добавить приведенный ниже код в файл Global.Asax.

protected void Application_BeginRequest()
        {
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                //These headers are handling the "pre-flight" OPTIONS call sent by the browser
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
                HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "TestHeaderToExpose");
                HttpContext.Current.Response.End();
            }
        }

Я написал его для опций.Пожалуйста, измените их так, как вам нужно.

Happy Coding !!

...