Angularjs问题 - $ http.get无法正常工作并更改为OPTIONS - 跨域

时间:2014-10-27 10:37:34

标签: angularjs service dependency-injection cross-domain

我是Angularjs的新手并尝试创建一个远程服务(位于" http://dev.testmyserver2"),以便在各种应用程序中使用(位于" http://dev.testmyserver &#34)

此服务使用Colfusion和Oracle数据库检索有关用户的各种数据。当我直接在浏览器中启动应用程序时,它非常有效。然而,当我试图从另一个应用程序调用此服务的功能(在工厂中定义)时(由于在此应用程序的主模块中调用的依赖项),http GET在OPTIONS中被修改(在firebug中可见)而我不能检索数据(http请求的状态代码为O)。正确调用该函数(警报"函数正确调用"或者正确调用此函数的console.log),但没有检索到该人的数据。

我认为它是跨域问题。但我不知道如何解决它。

这里有一些代码:

远程服务,包含从数据库中检索数据的功能:

  • MODULE - appRemoteService.js:

    var app=angular.module('RemoteService', ['ngRoute', 'ui.bootstrap']);
    
    app.config(function($routeProvider, $httpProvider, ngDialogProvider){
    
    // disable IE ajax request caching
    $httpProvider.defaults.cache = false;
    if (!$httpProvider.defaults.headers.get) {
        $httpProvider.defaults.headers.get = {};
    }
    $httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
    
    // Create the routes
    $routeProvider.when('/home',
    {
      templateUrl: 'template/allPersons.html',
      controller: 'ctrlPersons'
    
    })
    
    .when('/documentation',
    {
      templateUrl: 'template/documentation.html',
      controller: 'ctrlDocumentation'
    })      
    
    .otherwise({redirectTo:'/home'});  
    });    
    
    app.controller('ctrlPersons', function ($scope, FactoryRemoteService){
        FactoryRemoteService.getUserFromLogin("test").success(function(personInfo){
            alert(personInfo["VALUES"][0]["FIRSTNAME"]);
        });     
    });
    
  • FACTORY - appFactoryRemoteService.js:

    app.factory('FactoryRemoteService', function($http){
    var factory={};
    factory.getUserFromLogin=function(uid){
        Alert("Function correctly called");
        return $http.get('http://dev.testmyserver2/myapp.cfc?method=getUserFromLogin&login=' + uid);
    };
    
    return factory; 
    })
    

我的申请

  • MAIN FILE - index.html:

                          

        <title>My app</title>
    
        <link rel="stylesheet" href="lib/css/bootstrap-3.1.1/css/bootstrap.min.css">
        <link rel="stylesheet" href="lib/css/bootstrap-3.1.1/css/bootstrap-theme.min.css">
    
        <link rel="stylesheet" href="css/styles.css" rel="stylesheet">
        <link rel="stylesheet" href="css/select.css" rel="stylesheet">  
    
    </head>
    
    <body>
    
        <div class="container">
            <div class="spacer navbar">
    
                <h1 class="nav nav-pills navbar-left">MY APP</h1>
    
                <ul class="nav nav-pills navbar-right" data-ng-controller="NavbarController">
                    <li data-ng-class="{'active':getClass('/all-contacts')}"><a href="#/all-contacts">All contacts</a></li>
                    <li data-ng-class="{'active':getClass('/add-contacts')}"><a href="#/add-contacts">Add contacts</a></li>
                </ul>
    
            </div>
    
            <ng-view></ng-view>
    
      </div>
    
      <script src="lib/js/angular.min.js"></script>
      <script src="lib/js/angular-route.min.js"></script>     
      <script src="lib/js/angular-sanitize.min.js"></script>      
    
      <script src="lib/js/bootstrap.min.js"></script>
      <script src="lib/js/jquery.min.js"></script>
    
      <script src="lib/js/ui-bootstrap-tpls-0.11.0.min.js"></script>     
    
      <script src="app/app.js"></script>
      <script src="app/appService.js"></script>
    
      <script src="http://dev.testmyserver2/app/appRemoteService.js"></script>
      <script src="http://dev.testmyserver2/app/appFactoryRemoteService.js"></script>     
    
    </body>
    

  • MODULE - app.js:

    var app=angular.module('ContactsApp', ['ngRoute', 'ui.bootstrap', 'RemoteService']);
    
    // register the interceptor as a service
    app.factory('HttpInterceptor', ['$q', '$rootScope', function($q, $rootScope) {
       return {
            // On request success
            request : function(config) {
            // Return the config or wrap it in a promise if blank.
            return config || $q.when(config);
        },
    
        // On request failure
        requestError : function(rejection) {
            //console.log(rejection); // Contains the data about the error on the request.  
            // Return the promise rejection.
            return $q.reject(rejection);
        },
    
        // On response success
        response : function(response) {
            //console.log(response); // Contains the data from the response.
            // Return the response or promise.
            return response || $q.when(response);
        },
    
        // On response failure
        responseError : function(rejection) {
            //console.log(rejection); // Contains the data about the error.
            //Check whether the intercept param is set in the config array. 
            //If the intercept param is missing or set to true, we display a modal containing the error
            if (typeof rejection.config.intercept === 'undefined' || rejection.config.intercept)
            {
                //emitting an event to draw a modal using angular bootstrap
                $rootScope.$emit('errorModal', rejection.data);
            }
            // Return the promise rejection.
            return $q.reject(rejection);
        }
    };
    }]);
    
    app.config(function($routeProvider, $httpProvider){
    // disable IE ajax request caching
    $httpProvider.defaults.cache = false;
    if (!$httpProvider.defaults.headers.get) {
        $httpProvider.defaults.headers.get = {};
    }   
    $httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
    
    // Add the interceptor to the $httpProvider to intercept http calls
    $httpProvider.interceptors.push('HttpInterceptor');
    
    $routeProvider.when('/all-contacts',
    {
      templateUrl: 'template/allContacts.html',
      controller: 'ctrlContacts'
    
    })
    .when('/view-contacts/:contactId',
    {
      templateUrl: 'template/viewContact.html',
      controller: 'ctrlViewContacts'
    })
    .otherwise({redirectTo:'/all-contacts'});  
    
    });    
    
    
    app.controller('NavbarController', function($scope, $location){
    $scope.getClass=function(path){     
        if($location.path().substr(0,path.length) == path){
            return true;
        }else{
            return false;
        }       
    }
    });
    
    app.controller('ctrlViewContacts', function ($scope, $routeParams, RemoteServiceFactory){
    $scope.contact = null;
    
    // CALL OF THE REMOTE SERVICE
    RemoteServiceFactory.getUserFromLogin("test")
    .success(function(personInfo){
        alert(personInfo["VALUES"][0]["FIRSTNAME"]);
    })
    .error(function(personInfo, status){
        alert(status);
    }); 
    });
    

在各种论坛上进行了几次搜索后,我测试了一些解决方案,但问题始终存在。

例如我试图添加:

  //Enable cross domain calls
  $httpProvider.defaults.useXDomain = true;

  //Remove the header used to identify ajax call  that would prevent CORS from working
  delete $httpProvider.defaults.headers.common['X-Requested-With'];

或者

  //Reset headers to avoid OPTIONS request (aka preflight)
  $httpProvider.defaults.headers.common = {};
  $httpProvider.defaults.headers.post = {};
  $httpProvider.defaults.headers.put = {};
  $httpProvider.defaults.headers.patch = {};

您能帮我找一个解决方案来解决这个问题吗?

非常感谢您的回复

1 个答案:

答案 0 :(得分:0)

对于遇到相同问题的人,我使用XDomain第三方库找到了解决方案。您必须在服务所在的远程服务器上实现proxy.html文件,并在主应用程序的脚本标记中调用该文件。