为什么要返回 Undefined?

Why returning Undefined?

我正在开发一个应用程序,我在其中使用 Hapijs/Nodejs 和 AngularJS

这里是 Nodejs 部分

server.route({
  method: 'POST',
  path: '/login',
  handler: function(request, reply) {
    USER: request.payload.user,
    PWD: request.payload.password,
    PLANTA: request.payload.planta,
    PLANGROUP: request.payload.plantgroup,
    START_DATE: request.payload.startDate
  }
});

现在 Angular 部分

  .factory('LoginService', function($http, $q) {

    var defer = $q.defer();

    return {
      login: function() {
        $http.post('http://localhost:8000/login', {
          user: 'USRCP_HW',
          password: 'usrcp2012',
          planta: '6000',
          plantroup: 'E10',
          startDate: '2014-11-26'
        }).success(function(data) {
          console.log(data);
          return data;
        }).error(function(data, status){
          console.log(data, status);
          defer.reject(data);
        });
        return defer.promise;
      }
    }

  });

和登录控制器

  .controller('LoginCtrl', function($rootScope, $scope, $stateParams, LoginService) {

    $scope.login = function(data) {
      console.log(data);
    };

  });

我只需要记录数据,但我变得不确定。

如果在控制器中我这样做

$scope.login = function(data) {
  console.log(data);
  LoginService.login(data).then(function() {
    console.log(data);
  })
};

我在浏览器控制台中得到这个

OPTIONS http://localhost:8000/login

XMLHttpRequest cannot load http://localhost:8000/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The response had HTTP status code 501.

错误是因为同源策略限制,我觉得你可以使用相对路径登录url。

你不能return从这样的异步方法

.factory('LoginService', function ($http, $q) {

    var defer = $q.defer();

    return {
        login: function () {
            $http.post('/login', {
                user: 'USRCP_HW',
                password: 'usrcp2012',
                planta: '6000',
                plantroup: 'E10',
                startDate: '2014-11-26'
            }).success(function (data) {
                console.log(data);
                defer.resolve(data); //resolve the promise
                //you can't return from here as it is executed asynchronosly
            }).error(function (data, status) {
                console.log(data, status);
                defer.reject(data);
            });
            return defer.promise;
        }
    }

});

然后

.controller('LoginCtrl', function ($rootScope, $scope, $stateParams, LoginService) {

    $scope.login = function (data) {
        console.log(data);
    };

    LoginService.login().then($scope.login)

});

也不需要创建自定义承诺,因为 $http 也是 returns 一个

.factory('LoginService', function ($http, $q) {

    return {
        login: function () {
            return $http.post('http://localhost:8000/login', {
                user: 'USRCP_HW',
                password: 'usrcp2012',
                planta: '6000',
                plantroup: 'E10',
                startDate: '2014-11-26'
            }).success(function (data) {
                console.log(data);
                //you can't return from here as it is executed asynchronosly
            }).error(function (data, status) {
                console.log(data, status);
            });
        }
    }

});

然后

.controller('LoginCtrl', function ($rootScope, $scope, $stateParams, LoginService) {

    $scope.login = function (data) {
        console.log(data);
    };

    LoginService.login().success($scope.login)

});

您 运行 遇到了跨源资源问题。如果您从 http://127.0.0.1 打开网站,那么您的脚本必须将/ post 资源加载到 127.0.0.1,而不是像您在登录功能中所做的那样 localhost

此外,如果您使用的是 Apache 网络服务器,您可以将其添加到您的 .htaccess 文件中:

Header set Access-Control-Allow-Origin "*"

在这里阅读更多内容:

替换http://localhost:8000/login with /login if the site on which this script is running is also hosted on http://localhost:8000.

否则,您必须在 NodeJs 服务器上添加跨源策略:

app.all('*', function(req, res, next) {
       res.header("Access-Control-Allow-Origin", "*");
       next();
});

P.S:允许 CORS 的说明可能会有所不同,具体取决于您的 Web 服务器的风格。

回到您最初关于 CORS 的问题...在 Hapi 中,您可以逐条路由或全局配置。

var server = new Hapi.Server();

server.connection({
    port: process.env.PORT || 3333, 
    routes: { 
        cors: true 
    } 
});

您可以在此处找到更多信息:http://hapijs.com/api#route-options

或者,您可以按照 Karanvir Kang

的建议从同一域同时为客户端和 api 提供服务