【问题标题】:Why returning Undefined?为什么返回未定义?
【发布时间】:2015-06-18 14:41:51
【问题描述】:

我正在开发一个使用 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);
  })
};

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

选项http://localhost:8000/login

XMLHttpRequest 无法加载 http://localhost:8000/login。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,Origin 'http://127.0.0.1:8000' 不允许访问。响应的 HTTP 状态代码为 501。

【问题讨论】:

标签: javascript angularjs node.js hapijs


【解决方案1】:

这个错误是因为同源策略约束,我认为你可以使用相对路径作为登录url。

你不能从这样的异步方法返回

.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 也返回一个

.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)

});

【讨论】:

  • 我收到了这个:TypeError: LoginService.login(...).success is not a function
  • @ArunPJohny - 如果你不从 .error 处理程序抛出异常 - 如果登录抛出错误 - 你将无法在下一个 .error 处理程序中处理错误 - 你松了可链接性。 data 也应该从成功处理程序中返回,对吗?否则它不会出现在 $scope.login 函数中
【解决方案2】:

回到您最初关于 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 提供服务

【讨论】:

    【解决方案3】:

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

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

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

    更多阅读:

    【讨论】:

      【解决方案4】:

      如果运行此脚本的站点也托管在 http://localhost:8000 上,则将 http://localhost:8000/login 替换为 /login。

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

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

      P.S:允许 CORS 的说明可能会根据您的 Web 服务器风格而有所不同。

      【讨论】:

        猜你喜欢
        • 2014-10-24
        • 2021-12-11
        • 2019-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-28
        • 2018-07-11
        相关资源
        最近更新 更多