javascript AngularJS - HTTP 请求在控制器中发出预检请求,但不在 app.js 中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33214062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 16:13:31  来源:igfitidea点击:

AngularJS - HTTP request makes preflight request in controllers but not in app.js

javascriptjqueryangularjscorspreflight

提问by Luís Ferreira

I have an app which communicates with an external API. My app has a controller for each page. If I make a HTTP GET request in one of my controllers, it sends an OPTIONS preflight request, and I receive an error:

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

XMLHttpRequest cannot load http://dev/api/[email protected]&password=111111. Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.

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

However, if I copy paste the same code and paste it in my app.js file, it works flawlessly and returns me the data. I found out that this way it also only sends the GET request, and not the OPTIONS request.

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

I have tried adding the header content type as "text/plain" to my requests but that changes nothing. If I try making the requests with jQuery it works well, sending only the GET request, not matter if the code is in the controller or in the app.js file. Here is the complete controller code (in Angular form):

我曾尝试将标题内容类型作为“文本/纯文本”添加到我的请求中,但这没有任何改变。如果我尝试使用 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 protected]',
                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'];
 })

回答by Ahmad Baktash Hayeri

Have a research on the concept CORSwhich stands for Cross-Origin Resource Sharing. CORS is a technique by means of which resources on one location on the Internet are allowed to be requestedfrom other domains. As a security feature, cross-origin requests are forbidden by default due to a notion known as same origin policy.

对代表跨源资源共享的概念CORS进行研究。CORS 是一种允许从其他域请求Internet 上一个位置上的资源的技术。作为一项安全功能,由于称为同源策略的概念,默认情况下禁止跨源请求。

You are getting the error because you are trying to make a cross-originrequest, which is, in fact, being disallowed.

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

Try to delete the header that Angular sends by default to preventsuch requests:

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

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

Update

更新

I think, there can be only oneconfiguration block in a module. Therefore, you need to combine the two configurations you have into a single one:

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

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)