AngularJs $ http.post () não envia dados

337

Alguém poderia me dizer por que a seguinte declaração não envia os dados de postagem para o URL designado? O URL é chamado, mas no servidor quando imprimo $ _POST - recebo uma matriz vazia. Se eu imprimir uma mensagem no console antes de adicioná-la aos dados - ele mostrará o conteúdo correto.

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

Eu também tentei com os dados como string (com o mesmo resultado):

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

Parece estar funcionando quando eu o uso no seguinte formato:

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

mas existe uma maneira de fazer isso com o $ http.post () - e eu sempre tenho que incluir o cabeçalho para que ele funcione? Acredito que o tipo de conteúdo acima esteja especificando o formato dos dados enviados, mas posso enviá-lo como objeto javascript?

Spencer Mark
fonte
O URL está na mesma origem?
Fmquaglia 9/10/2013
Desculpe - sim para todos os exemplos é a mesma url
Spencer Mark
@ SpencerMark desculpe .. eu tentei acima do seu código de trabalho .. não está funcionando para mim.
Arul Sidthan

Respostas:

346

Eu tive o mesmo problema usando asp.net MVC e encontrei a solução aqui

Há muita confusão entre os novatos no AngularJS sobre o motivo pelo qual as $httpfunções abreviadas de serviço ( $http.post(), etc.) não parecem ser trocáveis ​​com os equivalentes do jQuery ( jQuery.post(), etc.)

A diferença está em como o jQuery e o AngularJS serializam e transmitem os dados. Fundamentalmente, o problema está no fato de o idioma de escolha do servidor não conseguir entender a transmissão do AngularJS nativamente ... Por padrão, o jQuery transmite dados usando

Content-Type: x-www-form-urlencoded

e a foo=bar&baz=moeserialização familiar .

O AngularJS , no entanto, transmite dados usando

Content-Type: application/json 

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

Serialização JSON, que infelizmente algumas linguagens de servidor da Web - principalmente PHP - não desserializam nativamente.

Funciona como um encanto.

CÓDIGO

// 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;
  }];
});
Felipe Miosso
fonte
7
Adicionei esse script ao caramanchão, use-o bower install angular-post-fix --save-devpara adicioná-lo.
Billy chama
existe uma maneira de mudar o método de transmissão de dados do php. Porque esse é o problema que estou tendo atualmente.
Demodave
11
Esse código funciona muito bem na maioria das vezes, mas tive problemas ao enviar uma hierarquia de objetos vazios ou mesmo valores vazios. Por exemplo, {a: 1, b: {c: {d: {}}}, e: undefined, f: null, g: 2} não serão codificados corretamente e o PHP o obterá como ["a" = > "1", "g" => "2"]. Toda a estrutura em "b", assim como "e" e "f", incluindo as próprias chaves - seriam perdidas. Postei código alternativo abaixo, com o qual a estrutura acima é decodificada como: ["a" => "1", "b" => ["c" => ["d" => ""]], "e" => "", "f" => "", "g" => "2"].
obe,
11
como devo implementar isso para multipart / form-data?
Davidlee
Soberbo :) Realmente funcionou como um encanto. Eu enfrentei o problema com Spring MVC
SKaul
115

Não está super claro acima, mas se você estiver recebendo a solicitação em PHP, poderá usar:

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

Para acessar uma matriz em PHP a partir de um AngularJS POST.

Don F
fonte
3
Eu precisava adicionar true para forçá-lo a uma matriz ao substituir a matriz $ _POST com ela. json_decode(file_get_contents('php://input'), true);
Jon
4
@Zalaboza, eu concordo que é difícil ter qualquer solução considerada 'universal', mas não concordo que seja 'hacky' --- php.net afirma: "file_get_contents () é a maneira preferida de ler o conteúdo de um arquivo em uma string. Ele usará técnicas de mapeamento de memória, se suportado pelo seu SO, para aprimorar o desempenho. " É verdade que não estamos lendo um arquivo nesta situação, mas estamos lendo os dados json publicados. Seria ótimo se você pudesse contribuir com uma nova resposta ou fornecer novas informações para ajudar os leitores (inclusive eu) a tomar uma decisão melhor sobre isso.
Don F
78

Você pode definir o "Tipo de conteúdo" padrão assim:

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

Sobre o dataformato:

Os métodos $ http.post e $ http.put aceitam qualquer valor de objeto JavaScript (ou uma string) como parâmetro de dados. Se os dados forem um objeto JavaScript, eles serão, por padrão, convertidos em uma sequência JSON.

Tente usar essa variação

function sendData($scope) {
    $http({
        url: 'request-url',
        method: "POST",
        data: { 'message' : message }
    })
    .then(function(response) {
            // success
    }, 
    function(response) { // optional
            // failed
    });
}
Denison Luz
fonte
9
Não parece funcionar. Acabei de experimentar a variação com os dados como string e: headers: {'Content-Type': 'application / x-www-form-urlencoded'} - e isso parece funcionar, mas existe uma maneira melhor de fazer isso isto?
Spencer Mark
2
Defina o tipo de conteúdo padrão conforme descrito acima e para dados não use o objeto js. Use string como esta: 'message =' + message Funciona para mim
gSorry
58

Eu tive um problema semelhante e gostaria de saber se isso também pode ser útil: 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'}
})

Saudações,

ericson.cepeda
fonte
Parece que os cabeçalhos foram a única alteração necessária. Obrigado!
Ben Guthrie
Obrigado, isso foi por mim :) O problema foi a codificação dos dados do POST.
Anónimo
33

Eu gosto de usar uma função para converter objetos para postar parâmetros.

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'}
})
Rômulo Collopy
fonte
30

Finalmente, isso foi resolvido no angular 1.4 usando $ httpParamSerializerJQLike

Consulte https://github.com/angular/angular.js/issues/6039

.controller('myCtrl', function($http, $httpParamSerializerJQLike) {
$http({
  method: 'POST',
  url: baseUrl,
  data: $httpParamSerializerJQLike({
    "user":{
      "email":"[email protected]",
      "password":"123456"
    }
  }),
  headers:
    'Content-Type': 'application/x-www-form-urlencoded'
})})
Stetzon
fonte
Estou enfrentando o problema POST 192.168.225.75:7788/procure/p/search 400 (Bad Request)
Anuj
19

Eu uso jQuery param com AngularJS pós requrest. Aqui está um exemplo ... crie o módulo de aplicativo AngularJS, onde myappé definido ng-appno seu código HTML.

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

Agora vamos criar um controlador de login e um e-mail e senha do 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
    });
}]);

Não gosto de explicar o código, é simples o suficiente para entender :) Observe que paramé do jQuery, portanto você deve instalar o jQuery e o AngularJS para fazê-lo funcionar. Aqui está uma captura de tela.

insira a descrição da imagem aqui

Espero que isso seja útil. Obrigado!

Madan Sapkota
fonte
10

Eu tive o mesmo problema com AngularJS e Node.js + Express 4 + Router

O roteador espera os dados da solicitação da postagem no corpo. Esse corpo estava sempre vazio se eu seguisse o exemplo do Angular Docs

Notação 1

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

Mas se eu o usasse nos dados

Notação 2

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

Editar 1:

Caso contrário, o roteador node.js. esperará os dados em req.body se for usada a notação 1:

req.body.msg

O que também envia as informações como carga útil JSON. Isso é melhor em alguns casos em que você tem matrizes no json e x-www-form-urlencoded causará alguns problemas.

funcionou. Espero que ajude.

conhecidos
fonte
10

Diferentemente do JQuery e pelo pedantismo, o Angular usa o formato JSON para transferência de dados POST de um cliente para o servidor (o JQuery aplica presumivelmente o código x-www-form-urlencoded, embora o JQuery e o Angular usem o JSON para a entrada de dados). Portanto, existem duas partes do problema: na parte do cliente js e na parte do servidor. Então você precisa:

  1. Coloque a parte do cliente js Angular assim:

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

E

  1. escreva na parte do servidor para receber dados de um cliente (se for php).

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

Nota: $ _POST não funcionará!

A solução funciona para mim, espero, e para você.

romano
fonte
8

Para enviar dados via Post methode com $httpangularjs, é necessário alterar

data: "message=" + messagecom data: $.param({message:message})

BERGUIGA Mohamed Amine
fonte
11
por que os dados: $ .param são necessários ao enviar dados de postagem do AngularJS?
blue-sky
7

Para aproveitar a resposta de @ felipe-miosso:

  1. Faça o download como um módulo AngularJS a partir daqui ,
  2. Instale-o
  3. Adicione-o ao seu aplicativo:

    var app = angular.module('my_app', [ ... , 'httpPostFix']);
Renaud
fonte
6

Não tenho reputação de comentar, mas em resposta / adição à resposta de Don F:

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

Um segundo parâmetro de trueprecisa ser adicionado à json_decodefunção para retornar corretamente uma matriz associativa:

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

Esten
fonte
6

Angular

  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();
        }
Malcolm Swaine
fonte
5

Este código resolveu o problema para mim. É uma solução em nível de aplicativo:

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";
  }
]);
Spartak Lalaj
fonte
5

Adicione isso no seu arquivo js:

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

e adicione isso ao seu arquivo de servidor:

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

Isso deve funcionar.

Jesus Erwin Suarez
fonte
4

Eu também enfrentei um problema semelhante e estava fazendo algo assim e isso não funcionou. Meu controlador Spring não conseguiu ler o parâmetro de dados.

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

Mas, lendo este fórum e o API Doc, tentei seguir o caminho e isso funcionou para mim. Se alguém também tiver um problema semelhante, você também pode tentar abaixo.

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

Verifique https://docs.angularjs.org/api/ng/service/ $ http # post para saber o que o param config faz. {data: '"id": "1"'} - Mapa de strings ou objetos que serão convertidos em URL? data = "id: 1"

Viraj
fonte
4

essa provavelmente é uma resposta tardia, mas acho que a maneira mais adequada é usar o mesmo pedaço de código de uso angular ao fazer uma solicitação "get" usando, você $httpParamSerializerprecisará injetá-la no seu controlador para que você possa simplesmente fazer o seguinte sem precisar use o Jquery, $http.post(url,$httpParamSerializer({param:val}))

app.controller('ctrl',function($scope,$http,$httpParamSerializer){
    $http.post(url,$httpParamSerializer({param:val,secondParam:secondVal}));
}
oneLeggedChicken
fonte
4

No meu caso, resolvo o problema assim:

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;

Você precisa usar JSON.stringify para cada parâmetro que contém um objeto JSON e, em seguida, construa seu objeto de dados com "$ .param" :-)

NB: Meu "objJSON" é um objeto JSON que contém conteúdo de matriz, número inteiro, string e html. Seu tamanho total é> 3500 caracteres.

bArraxas
fonte
3

Eu sei que aceitou resposta. Porém, seguir pode ajudar os futuros leitores, se a resposta não for adequada a eles por qualquer motivo.

Angular não faz ajax como jQuery. Enquanto eu tentava seguir o guia para modificar angular $httpprovider, encontrei outros problemas. Por exemplo, eu uso o codeigniter no qual a $this->input->is_ajax_request()função sempre falhava (que foi escrita por outro programador e usada globalmente, portanto não é possível alterar) dizendo que essa não era uma solicitação real do ajax.

Para resolvê-lo, tomei ajuda de promessa adiada . Eu testei no Firefox e ie9 e funcionou.

Eu tenho a seguinte função definida fora de qualquer código angular. Essa função faz chamadas regulares a jquery ajax e retorna objeto adiado / prometido (ainda estou aprendendo).

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

Então, eu estou chamando de código angular usando o código a seguir. Por favor, note que temos que atualizar o $scopemanualmente usando $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!");
    });

Esta pode não ser a resposta perfeita, mas me permitiu usar chamadas jquery ajax com angular e me permitiu atualizar o $scope.

Nis
fonte
2
A Angular possui seu próprio serviço de promessas chamado $ q desde 1.3. Não é necessário usar o JQuery para uma postagem.
22416 mbokil
3

Eu tive o mesmo problema no express .. para resolver, você precisa usar o bodyparser para analisar objetos json antes de enviar solicitações http.

app.use(bodyParser.json());
Muhammad Soliman
fonte
3

Estou usando os serviços Web asp.net WCF com js angulares e o código abaixo funcionou:

 $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;                    
       })

Espero que ajude.

Mehdi Rostami
fonte
3

Não encontrou um trecho de código completo de como usar o método $ http.post para enviar dados ao servidor e por que não estava funcionando nesse caso.

Explicações do trecho de código abaixo ...

  1. Estou usando a função jQuery $ .param para serializar os dados JSON para www post data
  2. Configurando o Tipo de Conteúdo na variável de configuração que será passada junto com a solicitação do angularJS $ http.post que instrui o servidor que estamos enviando dados no formato www post.

  3. Observe o método $ htttp.post, onde estou enviando o primeiro parâmetro como url, o segundo parâmetro como dados (serializado) e o terceiro parâmetro como config.

O código restante é auto-entendido.

$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;
            });
        };

Veja o exemplo de código do método $ http.post aqui .

Sheo Narayan
fonte
3

Se você estiver usando PHP, é uma maneira fácil de acessar uma matriz em PHP a partir de um AngularJS POST.

$params = json_decode(file_get_contents('php://input'),true);
Luis Felipe Barnett V
fonte
Este artigo pode ajudar as pessoas.
Stphane
3

Se estiver usando Angular> = 1.4 , aqui está a solução mais limpa usando o serializador fornecido pela 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';
});

E então você pode simplesmente fazer isso em qualquer lugar do seu aplicativo:

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

E ele serializará os dados corretamente param1=value1&param2=value2e os enviará /requesturlcom oapplication/x-www-form-urlencoded; charset=utf-8 cabeçalho Content-Type, como normalmente é esperado com solicitações POST nos terminais.

TL; DR

Durante minha pesquisa, descobri que a resposta para esse problema tem muitos sabores diferentes; alguns são muito complicados e dependem de funções personalizadas, outros dependem do jQuery e outros incompletos ao sugerir que você só precisa definir o cabeçalho.

Se você acabou de definir o Content-Typecabeçalho, o ponto final verá os dados POST, mas não estarão no formato padrão porque, a menos que você forneça uma string como sua dataou serialize manualmente seu objeto de dados, tudo será serializado como JSON por padrão e pode ser interpretado incorretamente no terminal.

por exemplo, se o serializador correto não foi definido no exemplo acima, ele seria visto no terminal como:

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

E isso pode levar a uma análise inesperada, por exemplo, o ASP.NET o trata como um nullnome de parâmetro, com {"param1":"value1","param2":"value2"}como valor; ou o Fiddler interpreta de outra maneira, com {"param1":"value1","param2":"value2"}o nome do parâmetro e nullo valor.

Saeb Amini
fonte
3

Semelhante ao formato de trabalho sugerido pelo OP e à resposta de Denison, exceto usando em $http.postvez de just $httpe ainda depende do jQuery.

A coisa boa sobre o uso do jQuery aqui é que objetos complexos são transmitidos corretamente; contra a conversão manual em parâmetros de URL que podem distorcer os dados.

$http.post( 'request-url', jQuery.param( { 'message': message } ), {
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
Benjamin Intal
fonte
2

Quando tive esse problema, o parâmetro que eu estava postando acabou sendo uma matriz de objetos em vez de um objeto simples.

D. Kermott
fonte
2

Recém-atualizado do angular 1.2 ao 1.3, encontramos um problema no código. Transformar um recurso levará a um loop infinito, porque (eu acho) da promessa $ mantendo novamente o mesmo objeto. Talvez ajude alguém ...

Eu poderia consertar isso da seguinte maneira:

[...]
  /**
 * 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
fonte
2

Estou usando o código de resposta aceito (código de Felipe) há um tempo e está funcionando muito bem (obrigado, Felipe!).

No entanto, recentemente descobri que há problemas com objetos ou matrizes vazios. Por exemplo, ao enviar este objeto:

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

O PHP parece não ver B e C. Entende isso:

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

Uma olhada na solicitação real no Chrome mostra isso:

A: 1
:
D: 2

Eu escrevi um trecho de código alternativo. Parece funcionar bem com meus casos de uso, mas não o testei extensivamente, portanto, use com cuidado.

Eu usei o TypeScript porque gosto de digitação forte, mas seria fácil converter para JS puro:

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("&");
    } ];
} ]);

É menos eficiente que o código de Felipe, mas não acho que isso importe muito, pois deve ser imediato comparado à sobrecarga geral da própria solicitação HTTP.

Agora o PHP mostra:

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

Até onde eu sei, não é possível fazer com que o PHP reconheça que Ba e C são matrizes vazias, mas pelo menos as chaves aparecem, o que é importante quando há código que depende de uma determinada estrutura, mesmo quando essencialmente vazio por dentro.

Observe também que ele converte se indefinido e nulo em cadeias vazias.

obe
fonte
TypeScript é a melhor maneira de codificar no POO com JavaScript!
Desfigurar
2

Basta colocar os dados que você deseja enviar como segundo parâmetro:

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

Outra forma que também funciona é:

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

Certifique-se de que paramName corresponde exatamente ao nome do parâmetro da função que você está chamando.

Fonte: método de atalho de publicação do AngularJS

Marco Lackovic
fonte
5
Alguém pode explicar por que essa resposta foi rejeitada?
Marco Lackovic
11
Não há como esta solução ser rejeitada, é a mais simples, mais curta e comprovada na documentação angular docs.angularjs.org/api/ng/service/$http
ainasiart
1

Eu resolvi isso pelos códigos abaixo:

Lado do cliente (Js):

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

observe que os dados são um objeto.

No servidor (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;
        }

e 'AllowCrossSiteJsonAttribute' é necessário para solicitações entre domínios:

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

Espero que isso tenha sido útil.

pixparker
fonte