AngularJs $ http.post () не отправляет данные

337

Может ли кто-нибудь сказать мне, почему следующее утверждение не отправляет данные сообщения на указанный 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?

Спенсер Марк
источник
URL в том же происхождении?
fmquaglia
Извините - да для всех примеров это тот же самый URL
Спенсер Марк
@SpencerMark извините .. я пробовал выше вашего рабочего кода .. он не работает для меня.
Арул Сирджан

Ответы:

346

У меня была такая же проблема при использовании asp.net MVC и я нашел решение здесь

Среди новичков в AngularJS много путаницы по поводу того, почему $httpсокращенные функции службы ( $http.post()и т. Д.) Не могут быть заменены эквивалентами jQuery (jQuery.post() и т. Д.)

Разница в том, как jQuery и AngularJS сериализуют и передают данные. По сути, проблема заключается в том, что выбранный вами серверный язык не может понять передачу AngularJS изначально ... По умолчанию jQuery передает данные, используя

Content-Type: x-www-form-urlencoded

и знакомая foo=bar&baz=moeсериализация.

AngularJS , однако, передает данные, используя

Content-Type: application/json 

и { "foo": "bar", "baz": "moe" }

Сериализация JSON, которая, к сожалению, некоторые языки веб-сервера, в частности, PHP, изначально не десериализуется.

Работает как шарм.

КОД

// Your app's root module...
angular.module('MyModule', [], function($httpProvider) {
  // Use x-www-form-urlencoded Content-Type
  $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';

  /**
   * 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;

    for(name in obj) {
      value = obj[name];

      if(value instanceof Array) {
        for(i=0; i<value.length; ++i) {
          subValue = value[i];
          fullSubName = name + '[' + i + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value instanceof Object) {
        for(subName in value) {
          subValue = value[subName];
          fullSubName = name + '[' + subName + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value !== undefined && value !== null)
        query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
    }

    return query.length ? query.substr(0, query.length - 1) : query;
  };

  // Override $http service's default transformRequest
  $httpProvider.defaults.transformRequest = [function(data) {
    return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
  }];
});
Фелипе Миоссо
источник
7
Я добавил этот сценарий, bower install angular-post-fix --save-devчтобы добавить его.
Билли Блейз
так есть ли способ изменить метод передачи данных php. Потому что это проблема, с которой я сталкиваюсь в настоящее время.
Demodave
1
Этот код прекрасно работает по большей части, но у меня были проблемы с ним при отправке иерархии пустых объектов или даже плоских пустых значений. Например, {a: 1, b: {c: {d: {}}}, e: undefined, f: null, g: 2} не будут правильно закодированы, и PHP получит его как ["a" = > "1", "g" => "2"]. Вся структура под «b», а также «e» и «f», включая сами ключи, будет потеряна. Ниже я разместил альтернативный код, с помощью которого вышеприведенная структура расшифровывается как: ["a" => "1", "b" => ["c" => ["d" => ""]], "e" => "", "f" => "", "g" => "2"].
ОБЕ
1
Как я должен реализовать это для multipart / form-data?
Давидли
Превосходно :) Действительно работал как шарм. Я столкнулся с проблемой со Spring MVC
SKaul
115

Это не супер ясно выше, но если вы получаете запрос в PHP, вы можете использовать:

$params = json_decode(file_get_contents('php://input'),true);

Чтобы получить доступ к массиву в PHP из AngularJS POST.

Дон Ф
источник
3
Мне нужно было добавить true, чтобы принудительно преобразовать его в массив при перезаписи массива $ _POST. json_decode(file_get_contents('php://input'), true);
Джон
4
@Zalaboza, я бы согласился, что трудно считать какое-либо решение «универсальным», но я не согласен с тем, что оно «хакерское» - php.net утверждает: «file_get_contents () - предпочтительный способ чтения содержимого файла в строку. Он будет использовать методы отображения памяти, если они поддерживаются вашей ОС, для повышения производительности. " Конечно, в этой ситуации мы не читаем файл, но тем не менее читаем опубликованные данные json. Было бы здорово, если бы вы могли предоставить новый ответ или предоставить новую информацию, чтобы помочь читателям (включая меня) принять лучшее решение по этому поводу.
Дон Ф
78

Вы можете установить «Content-Type» по умолчанию следующим образом:

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

О dataформате:

Методы $ http.post и $ http.put принимают любое значение объекта JavaScript (или строку) в качестве параметра данных. Если данные являются объектом JavaScript, по умолчанию они будут преобразованы в строку JSON.

Попробуйте использовать этот вариант

function sendData($scope) {
    $http({
        url: 'request-url',
        method: "POST",
        data: { 'message' : message }
    })
    .then(function(response) {
            // success
    }, 
    function(response) { // optional
            // failed
    });
}
Денисон Луз
источник
9
Это не похоже на работу. Я только что попробовал вариант с данными в виде строки и: headers: {'Content-Type': 'application / x-www-form-urlencoded'} - и это, кажется, работает, но есть ли лучший способ сделать Это?
Спенсер Марк
2
Установите тип содержимого по умолчанию, как описано выше, и для данных не используйте объект js. Используйте
следующую
58

У меня была похожая проблема, и мне интересно, может ли это быть полезным: https://stackoverflow.com/a/11443066

var xsrf = $.param({fkey: "key"});
$http({
    method: 'POST',
    url: url,
    data: xsrf,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

С Уважением,

ericson.cepeda
источник
Похоже, что заголовки были единственным изменением, в котором мы нуждались. Спасибо!
Бен Гатри
Спасибо, что сделал это для меня :) Проблема была в кодировании данных POST.
Даан
33

Мне нравится использовать функцию для преобразования объектов в пост-параметры.

myobject = {'one':'1','two':'2','three':'3'}

Object.toparams = function ObjecttoParams(obj) {
    var p = [];
    for (var key in obj) {
        p.push(key + '=' + encodeURIComponent(obj[key]));
    }
    return p.join('&');
};

$http({
    method: 'POST',
    url: url,
    data: Object.toparams(myobject),
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
Ромуло Коллопи
источник
30

Наконец, это было решено в Angular 1.4 с использованием $ httpParamSerializerJQLike

См. Https://github.com/angular/angular.js/issues/6039.

.controller('myCtrl', function($http, $httpParamSerializerJQLike) {
$http({
  method: 'POST',
  url: baseUrl,
  data: $httpParamSerializerJQLike({
    "user":{
      "email":"wahxxx@gmail.com",
      "password":"123456"
    }
  }),
  headers:
    'Content-Type': 'application/x-www-form-urlencoded'
})})
Stetzon
источник
Я сталкиваюсь с проблемой POST 192.168.225.75:7788/procure/p/search 400 (
неверный
19

Я использую JQuery Param с AngularJS после запроса. Вот пример ... создайте модуль приложения AngularJS, где myappопределен ng-appв вашем HTML-коде.

var app = angular.module('myapp', []);

Теперь давайте создадим контроллер входа в систему и POST электронную почту и пароль.

app.controller('LoginController', ['$scope', '$http', function ($scope, $http) {
    // default post header
    $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
    // send login data
    $http({
        method: 'POST',
        url: 'https://example.com/user/login',
        data: $.param({
            email: $scope.email,
            password: $scope.password
        }),
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    }).success(function (data, status, headers, config) {
        // handle success things
    }).error(function (data, status, headers, config) {
        // handle error things
    });
}]);

Я не люблю объяснять код, он достаточно прост для понимания :) Обратите внимание, что paramэто из jQuery, поэтому вы должны установить как jQuery, так и AngularJS, чтобы он работал. Вот скриншот.

введите описание изображения здесь

Надеюсь, это полезно. Спасибо!

Мадан Сапкота
источник
10

У меня была такая же проблема с AngularJS и Node.js + Express 4 + Router

Маршрутизатор ожидает данные от почтового запроса в теле. Это тело всегда было пустым, если я следовал примеру из 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.body, если используется нотация 1:

req.body.msg

Который также отправляет информацию в виде полезной нагрузки JSON. Это лучше в некоторых случаях, когда у вас есть массивы в вашем json, и x-www-form-urlencoded вызовет некоторые проблемы.

это сработало. Надеюсь, поможет.

alknows
источник
10

В отличие от JQuery и ради педантичности, Angular использует формат JSON для передачи данных POST от клиента к серверу (JQuery применяет предположительно x-www-form-urlencoded, хотя JQuery и Angular используют JSON для ввода данных). Поэтому есть две части проблемы: в клиентской части js и в вашей серверной части. Итак, вам нужно:

  1. поставь js угловую клиентскую часть вот так:

    $http({
    method: 'POST',
    url: 'request-url',
    data: {'message': 'Hello world'}
    });

И

  1. напишите в вашей серверной части, чтобы получить данные от клиента (если это php).

            $data               = file_get_contents("php://input");
            $dataJsonDecode     = json_decode($data);
            $message            = $dataJsonDecode->message;
            echo $message;     //'Hello world'

Примечание: $ _POST не будет работать!

Решение работает хорошо для меня, надеюсь, и для вас.

Римский
источник
8

Для отправки данных с помощью метода Post с $httpAngularjs необходимо изменить

data: "message=" + message, с участием data: $.param({message:message})

БЕРГИАГА Мохамед Амин
источник
1
почему data: $ .param требуется при отправке почтовых данных AngularJS?
голубое небо
7

Чтобы построить ответ @ felipe-miosso:

  1. Загрузите его как модуль AngularJS отсюда ,
  2. Установить его
  3. Добавьте его в свое приложение:

    var app = angular.module('my_app', [ ... , 'httpPostFix']);
Renaud
источник
6

У меня нет репутации, чтобы комментировать, но в ответ / дополнение к ответу Дона Ф.:

$params = json_decode(file_get_contents('php://input'));

Второй параметр trueдолжен быть добавлен в json_decodeфункцию для правильного возврата ассоциативного массива:

$params = json_decode(file_get_contents('php://input'), true);

Esten
источник
6

угловатый

  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();
        }
Малкольм Свейн
источник
5

Этот код решил проблему для меня. Это решение на уровне приложений:

moduleName.config(['$httpProvider',
  function($httpProvider) {
    $httpProvider.defaults.transformRequest.push(function(data) {
        var requestStr;
        if (data) {
            data = JSON.parse(data);
            for (var key in data) {
                if (requestStr) {
                    requestStr += "&" + key + "=" + data[key];
                } else {
                    requestStr = key + "=" + data[key];
                }
            }
        }
        return requestStr;
    });
    $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
  }
]);
Спартак Лалай
источник
5

Добавьте это в свой файл js:

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

и добавьте это в файл вашего сервера:

$params = json_decode(file_get_contents('php://input'), true);

Это должно работать.

Хесус Эрвин Суарес
источник
4

Я также столкнулся с подобной проблемой, и я делал что-то подобное, и это не сработало. Мой контроллер Spring не смог прочитать данные параметра.

var paramsVal={data:'"id":"1"'};
  $http.post("Request URL",  {params: paramsVal});  

Но, читая этот форум и API Doc, я попробовал следующий путь, и это сработало для меня. Если у кого-то также есть подобная проблема, Вы можете попробовать и ниже путь.

$http({
      method: 'POST',
      url: "Request URL",           
      params: paramsVal,
      headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'}
            });

Пожалуйста, проверьте https://docs.angularjs.org/api/ng/service/ $ http # post, чтобы узнать, что делает config config. {data: '"id": "1"'} - Карта строк или объектов, которые будут преобразованы в URL? data = "id: 1"

Viraj
источник
4

это, вероятно, поздний ответ, но я думаю, что самый правильный способ - использовать тот же фрагмент кода, который используется при выполнении запроса «get», используя его, вам $httpParamSerializerпридется внедрить его в свой контроллер, чтобы вы могли просто сделать следующее без необходимости использовать Jquery вообще, $http.post(url,$httpParamSerializer({param:val}))

app.controller('ctrl',function($scope,$http,$httpParamSerializer){
    $http.post(url,$httpParamSerializer({param:val,secondParam:secondVal}));
}
oneLeggedChicken
источник
4

В моем случае я решаю проблему следующим образом:

var deferred = $q.defer();

$http({
    method: 'POST',
    url: 'myUri', 
    data: $.param({ param1: 'blablabla', param2: JSON.stringify(objJSON) }),
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(
    function(res) {
        console.log('succes !', res.data);
        deferred.resolve(res.data);
    },
    function(err) {
        console.log('error...', err);
        deferred.resolve(err);
    }
);
return deferred.promise;

Вам необходимо использовать JSON.stringify для каждого параметра, содержащего объект JSON, а затем создать свой объект данных с помощью "$ .param" :-)

NB. Мой «objJSON» - это объект JSON, содержащий массив, целое число, строку и HTML-контент. Его общий размер> 3500 символов.

bArraxas
источник
3

Я знаю, что принял ответ. Но последующие могут помочь будущим читателям, если ответ не подходит им по какой-либо причине.

Angular не делает ajax так же, как jQuery. Пока я пытался следовать руководству по изменению угла $httpprovider, я столкнулся с другими проблемами. Например, я использую codeigniter, в котором$this->input->is_ajax_request() функция всегда неудачу (которая была написана другим программистом и использовалась глобально, поэтому не может быть изменена), говоря, что это не настоящий запрос ajax.

Чтобы решить это, я воспользовался помощью отсроченным обещанием . Я тестировал его в Firefox, и ie9, и он работал.

У меня есть следующая функция, определенная вне любого углового кода. Эта функция делает регулярный вызов jquery ajax и возвращает объект отложенного / обещания (я все еще учусь).

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

Затем я называю это угловым кодом, используя следующий код. Обратите внимание, что мы должны обновить $scopeвручную с помощью $scope.$apply().

    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!");
    });

Возможно, это не идеальный ответ, но он позволил мне использовать вызовы jquery ajax с angular и позволил мне обновить $scope.

Ниша
источник
2
Angular имеет собственную службу обещаний $ q начиная с версии 1.3. Не нужно использовать JQuery для поста.
Мбокил
3

У меня была такая же проблема в экспрессе .. чтобы решить, вы должны использовать bodyparser для анализа объектов json перед отправкой http запросов ..

app.use(bodyParser.json());
Мухаммед Солиман
источник
3

Я использую asp.net WCF веб-сервисы с угловой JS и код ниже работает:

 $http({
        contentType: "application/json; charset=utf-8",//required
        method: "POST",
        url: '../../operation/Service.svc/user_forget',
        dataType: "json",//optional
        data:{ "uid_or_phone": $scope.forgettel, "user_email": $scope.forgetemail },
        async: "isAsync"//optional

       }).success( function (response) {

         $scope.userforgeterror = response.d;                    
       })

Надеюсь, поможет.

Мехди Ростами
источник
3

Не удалось найти полный фрагмент кода о том, как использовать метод $ http.post для отправки данных на сервер и почему он не работает в этом случае.

Пояснения к фрагменту кода ниже ...

  1. Я использую функцию jQuery $ .param для сериализации данных JSON для публикации данных www
  2. Установка Content-Type в переменной config, которая будет передана вместе с запросом angularJS $ http.post, который указывает серверу, что мы отправляем данные в формате www post.

  3. Обратите внимание на метод $ htttp.post, где я отправляю 1-й параметр в виде URL-адреса, 2-й параметр в качестве данных (сериализованный) и 3-й параметр в качестве конфигурации.

Оставшийся код понятен самому себе.

$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 здесь .

Шео Нараян
источник
3

Если вы используете PHP, это простой способ получить доступ к массиву в PHP из AngularJS POST.

$params = json_decode(file_get_contents('php://input'),true);
Луис Фелипе Барнетт V
источник
3

Если используется 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заголовком Content-Type, как это обычно ожидается с запросами POST на конечных точках.

TL; DR

Во время моего исследования я обнаружил, что ответ на эту проблему может быть разным; некоторые из них очень сложны и зависят от пользовательских функций, некоторые зависят от jQuery, а некоторые неполны, предлагая установить заголовок.

Если вы просто установите Content-Typeзаголовок, конечная точка увидит данные POST, но они не будут в стандартном формате, потому что если вы не предоставите строку в качестве вашей dataили не сериализуете вручную ваш объект данных, все они будут сериализованы как JSON по умолчанию и может быть неправильно интерпретирован в конечной точке.

например, если в вышеприведенном примере не был задан правильный сериализатор, он будет выглядеть в конечной точке как:

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

И это может привести к неожиданному синтаксическому анализу, например, ASP.NET рассматривает его как nullимя параметра {"param1":"value1","param2":"value2"}и значение as; или Fiddler интерпретирует его по-другому, используя его {"param1":"value1","param2":"value2"}как имя параметра и nullкак значение.

Саиб Амини
источник
3

Аналогично предложенному рабочему формату OP и ответу Денисона, за исключением того, что он используется $http.postвместо just $httpи все еще зависит от jQuery.

Преимущество использования jQuery в том, что сложные объекты передаются правильно; против ручного преобразования в параметры URL, которые могут искажать данные.

$http.post( 'request-url', jQuery.param( { 'message': message } ), {
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
Бенджамин Интал
источник
2

Когда у меня возникла эта проблема, параметр, который я публиковал, оказался массивом объектов, а не простым объектом.

Д. Кермотт
источник
2

Только что обновил с угловой 1.2 до 1.3, обнаружил проблему в коде. Преобразование ресурса приведет к бесконечному циклу, потому что (я думаю) $ обещание снова содержит тот же объект. Может быть, это кому-то поможет ...

Я мог бы это исправить:

[...]
  /**
 * 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) {
[...]
tom_w
источник
2

Я уже давно использую принятый код ответа (код Фелипе), и он отлично работает (спасибо, Фелипе!).

Однако недавно я обнаружил, что у него есть проблемы с пустыми объектами или массивами. Например, при отправке этого объекта:

{
    A: 1,
    B: {
        a: [ ],
    },
    C: [ ],
    D: "2"
}

PHP, кажется, не видит B и C вообще. Это получает это:

[
    "A" => "1",
    "B" => "2"
]

Посмотрите на фактический запрос в Chrome показывает это:

A: 1
:
D: 2

Я написал альтернативный фрагмент кода. Кажется, это хорошо работает с моими вариантами использования, но я не тестировал это широко, поэтому используйте с осторожностью.

Я использовал TypeScript, потому что мне нравится строгая типизация, но было бы легко преобразовать его в чистый JS:

angular.module("MyModule").config([ "$httpProvider", function($httpProvider: ng.IHttpProvider) {
    // Use x-www-form-urlencoded Content-Type
    $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";

    function phpize(obj: Object | any[], depth: number = 1): string[] {
        var arr: string[] = [ ];
        angular.forEach(obj, (value: any, key: string) => {
            if (angular.isObject(value) || angular.isArray(value)) {
                var arrInner: string[] = phpize(value, depth + 1);
                var tmpKey: string;
                var encodedKey = encodeURIComponent(key);
                if (depth == 1) tmpKey = encodedKey;
                else tmpKey = `[${encodedKey}]`;
                if (arrInner.length == 0) {
                    arr.push(`${tmpKey}=`);
                }
                else {
                    arr = arr.concat(arrInner.map(inner => `${tmpKey}${inner}`));
                }
            }
            else {
                var encodedKey = encodeURIComponent(key);
                var encodedValue;
                if (angular.isUndefined(value) || value === null) encodedValue = "";
                else encodedValue = encodeURIComponent(value);

                if (depth == 1) {
                    arr.push(`${encodedKey}=${encodedValue}`);
                }
                else {
                    arr.push(`[${encodedKey}]=${encodedValue}`);
                }
            }
        });
        return arr;
    }

    // Override $http service's default transformRequest
    (<any>$httpProvider.defaults).transformRequest = [ function(data: any) {
        if (!angular.isObject(data) || data.toString() == "[object File]") return data;
        return phpize(data).join("&");
    } ];
} ]);

Он менее эффективен, чем код Фелипе, но я не думаю, что это имеет большое значение, поскольку он должен быть немедленным по сравнению с общими издержками самого HTTP-запроса.

Теперь PHP показывает:

[
    "A" => "1",
    "B" => [
        "a" => ""
    ],
    "C" => "",
    "D" => "2"
]

Насколько я знаю, PHP не может распознать, что Ba и C - пустые массивы, но, по крайней мере, появляются ключи, что важно, когда есть код, который опирается на определенную структуру, даже если он по существу пуст внутри.

Также обратите внимание, что он преобразует неопределенные s и нулевые s в пустые строки.

проектное землетрясение
источник
TypeScript лучший способ кодирования в POO с помощью JavaScript!
Изуродовать
2

Просто поместите данные, которые вы хотите отправить, как второй параметр:

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

Другая форма, которая также работает:

$http.post('request-url',  { params: { paramName: value } });

Убедитесь, что оно paramNameточно соответствует названию параметра функции, которую вы вызываете.

Источник: AngularJS пост ярлык метод

Марко Лацкович
источник
5
Кто-нибудь может объяснить, почему этот ответ был отклонен?
Марко Лацкович
1
От этого решения нельзя отказаться, оно самое простое, короткое и проверенное в угловой документации. Docs.angularjs.org/api/ng/service/$http
ainasiart
1

Я решил это с помощью следующих кодов:

Сторона клиента (Js):

     $http({
                url: me.serverPath,
                method: 'POST',
                data: data,
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            }).
                success(function (serverData) {
                    console.log("ServerData:", serverData);
    ......

обратите внимание, что данные являются объектом.

На сервере (ASP.NET MVC):

[AllowCrossSiteJson]
        public string Api()
        {
            var data = JsonConvert.DeserializeObject<AgentRequest>(Request.Form[0]);
            if (data == null) return "Null Request";
            var bl = Page.Bl = new Core(this);

            return data.methodName;
        }

и 'AllowCrossSiteJsonAttribute' необходим для междоменных запросов:

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
            base.OnActionExecuting(filterContext);
        }
    }

Надеюсь, это было полезно.

pixparker
источник