Настройка Access-Control-Allow-Origin в ASP.Net MVC - самый простой из возможных способов

У меня есть простой метод действия, который возвращает некоторый 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);

202
задан sideshowbarker 1 February 2019 в 23:25
поделиться

1 ответ

После борьбы в течение целого вечера я наконец заставил это работать. После некоторой отладки я нашел проблему, в которую я шел, был то, что мой клиент отправлял так называемый запрос Опций перед полетом, чтобы проверить, позволили ли приложению отправить запрос сообщения с источником, методами и предоставленными заголовками. Я не хотел использовать Owin или APIController, таким образом, я начал рыть и предложил следующее решение только с ActionFilterAttribute. Особенно "Access-Control-Allow-Headers" часть очень важна, как заголовки упомянули, там должны соответствовать заголовкам, которые отправит Ваш запрос.

using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MyNamespace
{
    public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpRequest request = HttpContext.Current.Request;
            HttpResponse response = HttpContext.Current.Response;

            // check for preflight request
            if (request.Headers.AllKeys.Contains("Origin") && request.HttpMethod == "OPTIONS")
            {
                response.AppendHeader("Access-Control-Allow-Origin", "*");
                response.AppendHeader("Access-Control-Allow-Credentials", "true");
                response.AppendHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE");
                response.AppendHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, X-RequestDigest, Cache-Control, Content-Type, Accept, Access-Control-Allow-Origin, Session, odata-version");
                response.End();
            }
            else
            {
                HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
                HttpContext.Current.Response.Cache.SetNoStore();

                response.AppendHeader("Access-Control-Allow-Origin", "*");
                response.AppendHeader("Access-Control-Allow-Credentials", "true");
                if (request.HttpMethod == "POST")
                {
                    response.AppendHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE");
                    response.AppendHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, X-RequestDigest, Cache-Control, Content-Type, Accept, Access-Control-Allow-Origin, Session, odata-version");
                }

                base.OnActionExecuting(filterContext);
            }
        }
    }
}

Наконец, мой метод действия MVC похож на это. Важный здесь должен также упомянуть Опции HttpVerbs, потому что иначе запрос перед полетом перестанет работать.

[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Options)]
[AllowCrossSiteJson]
public async Task<ActionResult> Create(MyModel model)
{
    return Json(await DoSomething(model));
}
1
ответ дан 23 November 2019 в 04:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: