有人能告诉我为什么下面的语句没有将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对象发送吗?


当前回答

我写了一个小的PHP帮助函数,允许这两种类型的输入参数:

function getArgs () {
    if ($input = file_get_contents('php://input') && $input_params = json_decode($input,true))
        return $input_params + $_POST + $_GET;
    return $_POST + $_GET;
}

用法:

<?php
    include("util.php"); # above code
    $request = getArgs();

    $myVar = "";
    if (isset($request['myVar']))
        $myVar = $request['myVar'];
?>

因此不需要修改JavaScript。

其他回答

  var payload = $.param({ jobId: 2 });

                this.$http({
                    method: 'POST',
                    url: 'web/api/ResourceAction/processfile',
                    data: payload,
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
                });

WebAPI 2

public class AcceptJobParams
        {
            public int jobId { get; set; }
        }

        public IHttpActionResult ProcessFile([FromBody]AcceptJobParams thing)
        {
            // do something with fileName parameter

            return Ok();
        }

我知道已经接受了答案。但是,如果这个答案因为任何原因不适合他们,下面的内容可能会对未来的读者有所帮助。

Angular不会像jQuery那样使用ajax。当我尝试按照指南修改angular $httpprovider时,我遇到了其他问题。例如,我使用codeigniter,其中$this->input->is_ajax_request()函数总是失败(这是由另一个程序员编写的,并在全局使用,所以不能改变)说这不是真正的ajax请求。

为了解决这个问题,我接受了延期承诺的帮助。我在Firefox和ie9上进行了测试,效果很好。

我在angular代码的外部定义了以下函数。这个函数使常规jquery ajax调用和返回延迟/承诺(我仍在学习)对象。

function getjQueryAjax(url, obj){
    return $.ajax({
        type: 'post',
        url: url,
        cache: true,
        data: obj
    });
}

然后我用下面的代码称它为角代码。请注意,我们必须使用$scope.$apply()手动更新$scope。

    var data = {
        media: "video",
        scope: "movies"
    };
    var rPromise = getjQueryAjax("myController/getMeTypes" , data);
    rPromise.success(function(response){
        console.log(response);
        $scope.$apply(function(){
            $scope.testData = JSON.parse(response);
            console.log($scope.testData);
        });
    }).error(function(){
        console.log("AJAX failed!");
    });

这可能不是完美的答案,但它允许我在angular中使用jquery ajax调用,并允许我更新$scope。

刚从angular 1.2更新到1.3,在代码中发现了一个问题。转换资源将导致一个无限循环,因为(我认为)$promise再次持有相同的对象。也许它会帮助到某人……

我可以解决这个问题:

[...]
  /**
 * The workhorse; converts an object to x-www-form-urlencoded serialization.
 * @param {Object} obj
 * @return {String}
 */
var param = function (obj) {
var query = '', name, value, fullSubName, subName, subValue, innerObj, i;

angular.forEach(obj, function(value, name) {
+    if(name.indexOf("$promise") != -1) {
+        return;
+    }

    value = obj[name];
    if (value instanceof Array) {
        for (i = 0; i < value.length; ++i) {
[...]

只是提出一个现代化版本的@FelipeMiosso的答案:

.config(["$httpProvider", function ($httpProvider) {

  function buildKey(parentKey, subKey) {
    return parentKey + "[" + subKey + "]";
  }

  function buildObject(key, value) {
    var object = {};
    object[key] = value;
    return object;
  }

  function join(array) {
    return array.filter(function (entry) {
      return entry;
    }).join("&");
  }

  function arrayToQueryString(parentKey, array) {
    return join(array.map(function (value, subKey) {
      return toQueryString(buildObject(buildKey(parentKey, subKey), value));
    }));
  }

  function objectToQueryString(parentKey, object) {
    return join(Object.keys(object).map(function (subKey) {
      return toQueryString(buildObject(buildKey(parentKey, subKey), object[subKey]));
    }));
  }

  function toQueryString(input) {
    return join(Object.keys(input).map(function (key) {
      var value = input[key];
      if (value instanceof Array) {
        return arrayToQueryString(key, value);
      } else if (value instanceof Object) {
        return objectToQueryString(key, value);
      } else if (undefined !== value && null !== value) {
        return encodeURIComponent(key) + "=" + encodeURIComponent(value);
      } else {
        return "";
      }
    }));
  }

  function isQueryStringEligible(input) {
    return null !== input && "object" === typeof input && "[object File]" !== String(input);
  }

  var interceptor = [function () {
    return {
      request: function (config) {
        if (0 <= ["post", "put", "patch"].indexOf(config.method.toLowerCase()) && isQueryStringEligible(config.data)) {
          config.headers["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
          config.data = toQueryString(config.data);
        }
        return config;
      }
    };
  }];

  $httpProvider.interceptors.push(interceptor);

}])

ES6版本:

.config(["$httpProvider", function ($httpProvider) {

  "use strict";

  const buildKey = (parentKey, subKey) => `${parentKey}[${subKey}]`;

  const buildObject = (key, value) => ({ [key]: value });

  const join = (array) => array.filter((entry) => entry).join("&");

  const arrayToQueryString = (parentKey, array) =>
    join(array.map((value, subKey) =>
      toQueryString(buildObject(buildKey(parentKey, subKey), value))));

  const objectToQueryString = (parentKey, object) =>
    join(Object.keys(object).map((subKey) =>
      toQueryString(buildObject(buildKey(parentKey, subKey), object[subKey]))));

  const toQueryString = (input) => join(Object.keys(input).map((key) => {
    const value = input[key];
    if (value instanceof Array) {
      return arrayToQueryString(key, value);
    } else if (value instanceof Object) {
      return objectToQueryString(key, value);
    } else if (undefined !== value && null !== value) {
      return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
    } else {
      return "";
    }
  }));

  const isQueryStringEligible = (input) =>
    null !== input && "object" === typeof input && "[object File]" !== String(input);

  const interceptor = [() => ({
    request(config) {
      if (0 <= ["post", "put", "patch"].indexOf(config.method.toLowerCase()) && isQueryStringEligible(config.data)) {
        config.headers["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
        config.data = toQueryString(config.data);
      }
      return config;
    }
  })];

  $httpProvider.interceptors.push(interceptor);

}])

没有找到如何使用$http的完整代码片段。Post方法将数据发送到服务器,以及为什么在这种情况下它不工作。

以下代码段的解释…

我使用jQuery $。param函数将JSON数据序列化为www post data 在配置变量中设置Content-Type,该变量将随angularJS $http请求一起传递。通知服务器我们将以WWW Post格式发送数据。 注意$ http。post方法,我发送的第一个参数作为url,第二个参数作为数据(序列化)和第三个参数作为配置。

剩下的代码是自己理解的。

$scope.SendData = function () {
           // use $.param jQuery function to serialize data from JSON 
            var data = $.param({
                fName: $scope.firstName,
                lName: $scope.lastName
            });

            var config = {
                headers : {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                }
            }

            $http.post('/ServerRequest/PostDataResponse', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
            })
            .error(function (data, status, header, config) {
                $scope.ResponseDetails = "Data: " + data +
                    "<hr />status: " + status +
                    "<hr />headers: " + header +
                    "<hr />config: " + config;
            });
        };

查看$http的代码示例。Post方法在这里。