AngularJS + Веб-API ASP.NET для междоменной проблемы

Двигаясь вперед с моим процессом разработки приложений для мобильных приложений, я обнаружил новое препятствие: совместное использование запросов с использованием Cross-Origing или CORS.

Я использую комбинацию AngularJS + jQuery Mobile (телефонный клиент Cordova) и веб-API ASP.NET(бэкэнд). Моя проблема в том, что я не смог выполнить POST-запрос (или любой другой тип запроса) для контроллера API.

Мой контроллер AngularJS использует метод службы $http.post() для вызова контроллера веб-API. Тем не менее, отладчик Chrome говорит, что вызов завершился неудачно в запросе OPTIONS (возможно, предпродажный запрос CORS).

Я внедрил селектор действий CORS из следующего сообщения: Включение CORS в проекте веб-API. Даже жестко я могу назвать метод api у Fiddler, AngularJS продолжает отказываться от запроса предвыборной информации OPTIONS.

Есть ли что-нибудь, о чем я должен знать об AngularJS и междоменных звонках? Любое возможное решение моего затруднительного положения?

Спасибо.

Ответ 1

Вы можете пропустить запрос опции предпросмотра, используя content-type: application/x-www-form-urlencoded.

AngularJS:

var user = {
   ID: 1,
   Name: 'test'
};

$http({
  url: "api.localhost/api/users/addUser",
  method: "POST",
  data: $.param(user),
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  withCredentials: true,
  }).success(function (data, status, headers, config) {
     console.log(data);
})

Веб-api:

[HttpPost]
public string AddUser(User user)
{
    // Do something
    return user.Name + " added";
}

Web.config

    <system.webServer>
        <validation validateIntegratedModeConfiguration="false" />
            <handlers>
                <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
                <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
                <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
                <remove name="OPTIONSVerbHandler" />
                <remove name="TRACEVerbHandler" />

                <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
                <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
                <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
            </handlers>
            <httpProtocol>
                <customHeaders>
                    <add name="Access-Control-Allow-Origin" value="http://localhost" />
                    <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept, Cache-Control" />
                    <add name="Access-Control-Allow-Credentials" value="true" />
                    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
                </customHeaders>
            </httpProtocol>
      </system.webServer>

Ответ 2

Во время обхода этой проблемы с помощью AngularJS 1.3 с помощью Microsoft Web API 2 я нашел простое решение проблемы с конфигурацией CORS.

  • Сначала от Nuget intall - Microsoft WebApi Cors

    Install-Package Microsoft.AspNet.WebApi.Cors
    
  • Затем в файле WebApiConfig.cs:

    var cors = new System.Web.Http.Cors.EnableCorsAttribute("www.my-angular-web-site.com", "*", "*");
    
    config.EnableCors(cors);
    

Вы также можете включить CORS везде с * вместо вашего веб-сайта, но это побеждает цель CORS и открывает дыры в безопасности, но вы можете сделать это для тестирования.

В сборке WebApi.Cors также можно включить контроллер cors контроллером или с другими подробными деталями. Другие подробности можно найти здесь на веб-сайте API.

Ответ 3

Ознакомьтесь с объектами Thinktecture Cors, с помощью которых (nugettable) вы можете получить полную поддержку CORS в WebApi без собственного кода.

Даже при правильной реализации CORS у меня была действительно странная проблема с IIS 7, которая была решена путем включения всех глаголов для WebDav (да, WebDav - не спрашивайте меня, почему я просто следовал инструкциям в сообщении в блоге: D).

Сделайте это:

  • Откройте диспетчер IIS, перейдите к картографированию обработчика вашего приложения.
  • Дважды щелкните обработчик WebDav
  • Нажмите "Ограничение запроса"
  • На вкладке "Глаголы" выберите "Все глаголы".

Опять же, не знаю, почему WebApi использует WebDav, но это решает проблемы с POST и DELETE, которые не будут работать, несмотря на правильную реализацию CORS.