有人能告诉我为什么下面的语句没有将post数据发送到指定的url吗?url被调用,但在服务器上,当我打印$_POST -我得到一个空数组。如果我在控制台中打印消息,然后将其添加到数据-它显示了正确的内容。

$http.post('request-url',  { 'message' : message });

我也尝试过将数据作为字符串(具有相同的结果):

$http.post('request-url',  "message=" + message);

当我以以下格式使用它时,它似乎正在工作:

$http({
    method: 'POST',
    url: 'request-url',
    data: "message=" + message,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});

但是是否有一种方法可以用$http.post() -我总是必须包括头以便它工作吗?我相信上面的内容类型是指定发送数据的格式,但我可以把它作为javascript对象发送吗?


当前回答

我在使用AngularJS和Node.js + Express 4 + Router时也遇到了同样的问题

路由器期望从post的请求中得到数据。如果我遵循Angular Docs中的例子,这个主体总是空的

符号1

$http.post('/someUrl', {msg:'hello word!'})

但如果我把它用在数据中

符号2

$http({
       withCredentials: false,
       method: 'post',
       url: yourUrl,
       headers: {'Content-Type': 'application/x-www-form-urlencoded'},
       data: postData
 });

编辑1:

否则node.js路由器将期望req中的数据。正文(如使用符号1):

req.body.msg

它还将信息作为JSON有效负载发送。在json和x-www-form-urlencoded中有数组的某些情况下,这是更好的。

它工作。希望能有所帮助。

其他回答

当我遇到这个问题时,我发布的参数原来是一个对象数组,而不是一个简单的对象。

如果使用Angular >= 1.4,下面是使用Angular提供的序列化器的最简洁的解决方案:

angular.module('yourModule')
  .config(function ($httpProvider, $httpParamSerializerJQLikeProvider){
    $httpProvider.defaults.transformRequest.unshift($httpParamSerializerJQLikeProvider.$get());
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
});

然后你可以简单地在你的应用的任何地方做这个:

$http({
  method: 'POST',
  url: '/requesturl',
  data: {
    param1: 'value1',
    param2: 'value2'
  }
});

它会正确地将数据序列化为param1=value1&param2=value2,并将其发送到/requesturl,并使用application/x-www-form-urlencoded;charset=utf-8内容类型报头,因为它通常是端点上POST请求所期望的。

博士TL;

在我的研究中,我发现这个问题的答案有很多种;一些是非常复杂的,依赖于自定义函数,一些依赖于jQuery和一些是不完整的,建议你只需要设置头。

如果您只是设置Content-Type报头,端点将看到POST数据,但它不会是标准格式,因为除非您提供一个字符串作为数据,或者手动序列化数据对象,否则在默认情况下,它都将被序列化为JSON,并且可能在端点被错误地解释。

例如,如果在上面的例子中没有设置正确的序列化器,它将在端点中被视为:

{"param1":"value1","param2":"value2"}

这可能导致意想不到的解析,例如ASP。NET将其视为空参数名,用{"param1":"value1","param2":"value2"}作为值;或者Fiddler以另一种方式解释它,用{"param1":"value1","param2":"value2"}作为参数名,用null作为值。

与JQuery不同,出于学究的考虑,Angular使用JSON格式进行POST 数据从客户端传输到服务器端(JQuery应用x-www-form-urlencoded,尽管JQuery和Angular使用JSON进行数据输入)。因此有两个部分的问题:在js客户端部分和在你的服务器部分。所以你需要:

把js的Angular客户端部分像这样放: http({美元 方法:“文章”, url:“请求url”, data: {'message': 'Hello world'} });

AND

写入服务器部分以接收来自客户端的数据(如果是php)。 $data = file_get_contents("php://input"); $ datasondecode = json_decode($data); $message = $dataJsonDecode->消息; echo $消息;/ /“Hello world”

注意:$_POST将不起作用!

希望这个方法对我有用,对你也有用。

It's not angular's fault. Angular is designed to work in JSON world. So when $http service send AJAX request, it send all your data as a payload, not as form-data so that your backend application can handle it. But jQuery does some things internally. You instruct jQuery's $ajax module to bind form-data as JSON but before sending AJAX request, it serialized JSON and add application/x-www-form-urlencoded header. This way your backend application able to received form-data in form of post parameters and not JSON.

但是你可以修改angular $http服务的默认行为

添加标题 序列化json

$httpParamSerializerJQLike是angular的内置服务,它以同样的方式序列化json。jQuery的参数。

$http({
    method: 'POST',
    url: 'request-url',
    data: $httpParamSerializerJQLike(json-form-data),
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;'
    }
});

如果你需要一个插件先将表单数据序列化成JSON,可以使用这个插件https://github.com/marioizquierdo/jquery.serializeJSON

你可以这样设置默认的“Content-Type”:

$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";

关于数据格式:

美元的http。Post和$http。put方法接受任何JavaScript对象(或字符串)值作为其数据参数。如果data是一个JavaScript对象,默认情况下,它将被转换为JSON字符串。

试着使用这种变化

function sendData($scope) {
    $http({
        url: 'request-url',
        method: "POST",
        data: { 'message' : message }
    })
    .then(function(response) {
            // success
    }, 
    function(response) { // optional
            // failed
    });
}