Angular $http POST 从 ExpressJS 获取 null

Posted

技术标签:

【中文标题】Angular $http POST 从 ExpressJS 获取 null【英文标题】:Angular $http POST gets null from ExpressJS 【发布时间】:2015-07-08 02:28:49 【问题描述】:

我在后端和使用 Node 并尝试设置 $http POST 请求以将表单发送到 Express 方面缺乏经验。每次我提出请求时,我的回调data 都是null。也许我的 Express 路由配置不正确?我正在使用 Angular 与 Express/Node 通信,以通过 nodemailer(我已经正确配置)发送电子邮件。

这是我的$http POST 请求:

client/service/emailer/emailer.js

angular.module('public').factory('EmailerService',function($http) 
    return 
            postEmail: function(emailData, callback) 
            console.log('call http with object', emailData);
            $http(
                method: 'POST',
                url: 'http://my-website.com/server/routes/emailer',
                data: emailData,
                headers:  "Content-Type": "application/json" ,
                responseType: 'json'
            ).success(function(data, status, headers, config) 
                console.log('success', data, status);
            ).error(function(data, status, headers, config) 
                console.log('error', data, status);
            ).catch(function(error)
                console.log('catch', error);
            );
        
    ;
);

这是我的服务器端 Express 配置:

服务器/路由/emailer.js

var express = require('express');
var router = express.Router();
var bodyParser = require('body-parser');
var logger = require('morgan');

var app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded( extended: false ));
app.use(logger('dev'));

app.post('/emailer', function(req,res) 
    // NOTHING LOGS HERE
    console.log(res, req, req.body, res.body);
);

module.exports = app;

这里没有任何日志记录到控制台,$http 请求的错误处理返回以下内容:

emailer.js:4 call http with  Object email: "asdf"
angular.js:8632 OPTIONS http://matt-mcdaniel.com/server/routes/emailer net::ERR_CONNECTION_TIMED_OUT(anonymous function) @ angular.js:8632sendReq @ angular.js:8426$get.serverRequest @ angular.js:8146deferred.promise.then.wrappedCallback @ angular.js:11682deferred.promise.then.wrappedCallback @ angular.js:11682(anonymous function) @ angular.js:11768$get.Scope.$eval @ angular.js:12811$get.Scope.$digest @ angular.js:12623$get.Scope.$apply @ angular.js:12915(anonymous function) @ angular.js:19264jQuery.event.dispatch @ jquery.js:4676jQuery.event.add.elemData.handle @ jquery.js:4360
emailer.js:14 error null 0
emailer.js:16 catch Object data: null, status: 0, headers: function, config: Object, statusText: ""

为了更好的衡量,而且由于我是学习 Express 的新手,我将发布我的服务器端 app.js

服务器/app.js

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var compression = require('compression');
var routes = require('./routes/index');
var contact = require('./routes/emailer');

var app = express();

// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded( extended: false ));
app.use(cookieParser());
app.use(compression());
app.use(require('connect-livereload')(
    port: 35729,
    ignore: ['.js']
));

/** Development Settings */
if (app.get('env') === 'development') 
    // This will change in production since we'll be using the dist folder
    app.use(express.static(path.join(__dirname, '../client')));
    // This covers serving up the index page
    // app.use(express.static(path.join(__dirname, '../client/.tmp')));
    // app.use(express.static(path.join(__dirname, '../client/public')));

    // Error Handling
    app.use(function(err, req, res, next) 
        res.status(err.status || 500);
        res.render('error', 
            message: err.message,
            error: err
        );
    );


/**
 * Production Settings
 */
if (app.get('env') === 'production') 

    // changes it to use the optimized version for production
    app.use(express.static(path.join(__dirname, '/dist')));

    // production error handler
    // no stacktraces leaked to user
    app.use(function(err, req, res, next) 
        res.status(err.status || 500);
        res.render('error', 
            message: err.message,
            error: 
        );
    );



module.exports = app;

app.use(function(req, res) 
    res.sendfile(__dirname + '/dist/index.html');
);

这是我的文件结构:

【问题讨论】:

您能否添加您的 client/app.js 的相关部分,该部分通过您的 EmailService 工厂调用 POST? 我不知道除了“var contact = require('./routes/emailer');”之外我还需要向 app.js 添加任何内容。我想我不确定如何在后端调用 POST 请求... 【参考方案1】:

你的emailer.js 路由肯定有一些问题。你应该只在那里有路由逻辑,你不应该重新创建你的快速应用程序。 Express 为您提供了一个Router 对象来简化此操作。例如,您的 emailer.js 可能如下所示:

module.exports = express.Router()
    .post('/emailer', function(req,res) 
        console.log(res, req, req.body, res.body);
        res.json(hello:'world');
    );

您可以像这样在server/app.js 中映射这条路线:

var emailer = require('./routes/emailer');

// ...After all app.use statements, but *before* your error handlers
app.use('/server/routes', emailer);

【讨论】:

数据仍然返回null。我应该如何通过我的服务调用我的$http 指向这条路线,我应该像上面显示的那样输入整个地址吗? 哦,您的响应类型是 JSON,而我的代码只是返回一个字符串。这可能是问题所在。我会更新我的答案。此外,您应该能够使用角度代码中的相对路径,例如 url: '/server/routes/emailer' 解决了!谢谢。

以上是关于Angular $http POST 从 ExpressJS 获取 null的主要内容,如果未能解决你的问题,请参考以下文章

从http post请求下载文件 - Angular 6

从Angular2应用程序发送http post请求时如何启用CORS

从 Angular 2 客户端到 Node.js 服务器的 HTTP POST 请求

无法反序列化从 Springboot POST 映射函数上的 Angular http post 请求发送的 POJO

从 Angular 向 Asp.net 发送 post 请求时出现错误 405

ionic 2 angular 2 从 ion-select 中获取值以发送 http post