AngularJS - HTTP请求在控制器中进行预检请求,但在app.js

时间:2015-10-19 12:11:36

标签: javascript jquery angularjs cors preflight

我有一个与外部API通信的应用。我的应用程序为每个页面都有一个控制器如果我在我的一个控制器中发出HTTP GET请求,它会发送一个OPTIONS预检请求,并收到错误:

  

XMLHttpRequest无法加载http://dev/api/?email_address=email@email.com&password=111111。请求标头字段预检响应中的Access-Control-Allow-Headers不允许授权。

但是,如果我复制粘贴相同的代码并将其粘贴到我的app.js文件中,它会完美无缺地运行并返回数据。我发现这种方式它也只发送GET请求,而不是OPTIONS请求。

我已经尝试将标题内容类型添加为“text / plain”到我的请求但是没有任何改变。如果我尝试用jQuery发出请求它运行良好,只发送GET请求,无论代码是在控制器中还是在app.js文件中。这是完整的控制器代码(以Angular形式):

angular.module('website.homepage', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/', {
        templateUrl: 'homepage/view.html',
        controller: 'HomepageCtrl',
        resolve: {
            data: function($q, $http, $route, $rootScope) {
                var deferred = $q.defer();
                $http({method: 'GET', url: $rootScope.apiURL + 'home'})
                    .then(function(data) {
                        deferred.resolve(data);
                    });
                return deferred.promise;
            }
        }
    })
}])
.controller('HomepageCtrl', function ($scope, $http, data) {

        var url = "http://dev.api";

        $http({
            url: url,
            dataType: 'json',
            method: "GET",
            data: '',
            params: {
                email_address: 'email@email.com',
                password: '111111'
            },
            headers: {
                'Content-Type': 'text/plain'
            }
        })
        .success(function(response) {
            console.log(response);

        })
       .error(function(response) {
            console.log(response);
       });


 })
 .config(function ( $httpProvider) {
     delete $httpProvider.defaults.headers.common['X-Requested-With'];
 })

1 个答案:

答案 0 :(得分:3)

CORS概念进行研究,该概念代表跨源资源共享。 CORS是一种技术,通过该技术允许来自其他域的请求的因特网上的一个位置上的资源。 作为一项安全功能,默认情况下禁止跨源请求,因为这一概念称为same origin policy

您收到错误是因为您尝试发出 跨域 请求,实际上这是不被允许的。

尝试删除Angular默认发送到阻止此类请求的标头:

angular.module('someModule') 
.config(function ( $httpProvider) {        
    delete $httpProvider.defaults.headers.common['X-Requested-With'];
})...

更新

我认为,模块中只能有一个配置块。因此,您需要将两种配置合并为一个:

angular.module('website.homepage', ['ngRoute'])
.config(['$routeProvider', '$httpProvider', function($routeProvider, $httpProvider) { // inject the other provider here
$routeProvider.when('/', {
    templateUrl: 'homepage/view.html',
    controller: 'HomepageCtrl',
    resolve: {
        data: function($q, $http, $route, $rootScope) {
            var deferred = $q.defer();
            $http({method: 'GET', url: $rootScope.apiURL + 'home'})
                .then(function(data) {
                    deferred.resolve(data);
                });
            return deferred.promise;
        }
      }
    });

    delete $httpProvider.defaults.headers.common['X-Requested-With'];
}])...   // rest of your code (services, factories, whatever)