【问题标题】:POST by Angular to server (Which is written in Node Express) not recognize parametersAngular POST 到服务器(用 Node Express 编写)无法识别参数
【发布时间】:2014-02-11 18:44:31
【问题描述】:

我是 Node Express 的新手,如果我问了一些愚蠢的问题,我很抱歉。 我正在设计一个由两部分组成的应用程序 1- 服务器端 2- 客户端。 这两个部分是完全独立的。我在 localhost:3000 上运行服务器端,在 localhost:9000 上运行客户端。我正在尝试通过客户端应用程序 POST 到服务器端,但我从服务器得到的响应显示它无法识别我的 POST 参数。这是我期望的回应:

{
  "make": "Toyota",
  "model": "Corolla",
  "year": "2013"
}

这是我目前得到的回复:

{
  "{\"make\":\"Toyota\",\"model\":\"Corolla\",\"year\":\"2013\"}": ""
}

当我通过服务器用户界面发布时,它会正确响应,但是当我尝试使用客户端应用程序发布时,它无法识别参数。

这是我写的代码:

1- 服务器端代码

app.js:

'use strict';

/*
 * Express Dependencies
 */
var express = require('express');
var app = express();
var port = 3000;

/*
 * Use Handlebars for templating
 */
var exphbs = require('express3-handlebars');
var hbs;

// For gzip compression
app.use(express.compress());
//Middleware to parse the request body
app.use(express.urlencoded());

/*
 * Config for Production and Development
 */
if (process.env.NODE_ENV === 'production') {
    // Set the default layout and locate layouts and partials
    app.engine('handlebars', exphbs({
        defaultLayout: 'main',
        layoutsDir: 'dist/views/layouts/',
        partialsDir: 'dist/views/partials/'
    }));

    // Locate the views
    app.set('views', __dirname + '/dist/views');

    // Locate the assets
    app.use(express.static(__dirname + '/dist/assets'));

} else {
    app.engine('handlebars', exphbs({
        // Default Layout and locate layouts and partials
        defaultLayout: 'main',
        layoutsDir: 'views/layouts/',
        partialsDir: 'views/partials/'
    }));

    // Locate the views
    app.set('views', __dirname + '/views');

    // Locate the assets
    app.use(express.static(__dirname + '/assets'));
}

// Set Handlebars
app.set('view engine', 'handlebars');



/*
 * Routes
 */
// Index Page
app.get('/', function(request, response, next) {
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
response.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
response.setHeader('Access-Control-Allow-Credentials', 'true');
    response.render('index');
});


app.post('/command', function(request, response) {
    response.setHeader('Content-type', 'application/json; charset=utf-8');
    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    response.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
    response.setHeader('Access-Control-Allow-Credentials', 'true');

        console.log(request.body.make);
        console.log(request.body.model);
        console.log(request.body.year);

        response.send(request.body);
    // ...
});

/*
 * Start it up
 */
app.listen(process.env.PORT || port);
console.log('Express started on port ' + port);

index.handlebars

<div class="container">

    <form action="command" method="post">

    <label>Make</label>
    <input type="text" name="make" id = "make" value="" />
    <br />
    <label>Model</label>
    <input type="text" name="model" id = "model" value="" />
    <br />
    <label>Year</label>
    <input type="text" name="year"  id = "year" value="" />
    <br />
    <input type="submit" value="Submit" />

    </form>

</div>

2- 客户端
service.js

myAppServices.factory('postServices', function($http, $q, $rootScope){
    var dataArray = [];
    var sendPost = function(selectedMake, selectedModel, selectedYear){

    var defer = $q.defer();

    $http({
            method:'POST',
        url: 'http://localhost:3000/command',
        data: {
          make:selectedMake, 
          model:selectedModel, 
          year:selectedYear
        },

        headers : {
                   'Content-Type' : 'application/x-www-form-urlencoded; charset=utf-8'
             }
            }).success(function (data, status, headers, config) {
              defer.resolve(data);
              // $rootScope.$broadcast('UPDATE_RESULT_TABLE', data);
              dataArray.push(data);

            }).error(function (data, status, headers, config) {
                alert("Fail");
                defer.reject({});
            });

    return defer.promise;
}

return {
    dataArray: dataArray,
    sendPost: sendPost
    }
});

controller.js

myAppControllers.controller('postCriteria', function($scope, $http, postServices, $location) {
    //We define the following line to get the values from child and put it to parent
    $scope.carData = {car:'', Model:'', Year:''};

    $scope.searchCar = function  () {
      postServices.sendPost($scope.carData.car, $scope.carData.Model, $scope.carData.Year).then(function(data){
                        $location.path('/results');
                });
        }         
    });

【问题讨论】:

    标签: javascript node.js angularjs express


    【解决方案1】:

    看起来您的回答是正确的,它只是序列化版本,被强制输入一个不太有效的键/值对。 HTTP 不支持在请求正文中发送非序列化数据。如果您将服务器代码中的最后一行修改为:

    response.send(JSON.parse(request.body));
    

    我认为你应该得到你想要的回应。

    【讨论】:

    • 当我通过服务器表单发布时,它会正确响应,但是当我尝试使用客户端应用程序发布时,它无法识别参数。顺便说一句,我更改了代码中的那一行,它使服务器端崩溃,因为它已经是一个 JSON 对象。
    【解决方案2】:

    我觉得你一定要用快递json.response function

    类似这样的:

    res.json(200, JSON.parse(request.body));
    

    【讨论】:

      【解决方案3】:

      问题在于 AngularJS 将 POST 数据作为 JSON 数据发送:

      我可以看到两种解决方案:

      • $http 方法中使用params 而不是data。在这种情况下,您的对象将作为 GET 参数在 URL 中发送,而不是在请求正文中,因此您必须在服务器上编写 response.send(request.query); 而不是 response.send(request.body);
      • 您可以通过传递字符串而不是对象来执行 POST 数据。使用 jQuery,它可以像编写一样简单:

       

      $http({
          ...
          data: $.param({make:'Toyota',model:'Corolla',year:'2013'})
          ...
      });
      

      如果你不介意使用 jQuery,第二个变体对我来说更可取:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-20
        • 1970-01-01
        • 1970-01-01
        • 2015-12-12
        • 2016-09-06
        • 1970-01-01
        相关资源
        最近更新 更多