validar validacion solo pattern letras formularios formulario enviar ejemplos con antes ajax angularjs post angular-http

ajax - validacion - validar formulario jquery antes de enviar



¿Cómo puedo publicar datos como datos de formulario en lugar de una carga útil de solicitud? (22)

En el código a continuación, el método AngularJS $http llama a la URL y envía el objeto xsrf como una "Carga útil de solicitud" (como se describe en la pestaña de la red del depurador Chrome). El método jQuery $.ajax hace la misma llamada, pero envía xsrf como "Datos de formulario".

¿Cómo puedo hacer que AngularJS envíe xsrf como datos de formulario en lugar de una carga útil de solicitud?

var url = ''http://somewhere.com/''; var xsrf = {fkey: ''xsrf key''}; $http({ method: ''POST'', url: url, data: xsrf }).success(function () {}); $.ajax({ type: ''POST'', url: url, data: xsrf, dataType: ''json'', success: function() {} });


A partir de AngularJS v1.4.0, hay un servicio $httpParamSerializer que convierte cualquier objeto en una parte de una solicitud HTTP de acuerdo con las reglas que se enumeran en la página de documentos .

Se puede usar así:

$http.post(''http://example.com'', $httpParamSerializer(formDataObj)). success(function(data){/* response status 200-299 */}). error(function(data){/* response status 400-999 */});

Recuerde que para una publicación de formulario correcta, se debe cambiar el encabezado Content-Type . Para hacer esto globalmente para todas las solicitudes POST, este código (tomado de la media respuesta de Albireo) se puede usar:

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

Para hacer esto solo para la publicación actual, la propiedad de headers del objeto de solicitud debe modificarse:

var req = { method: ''POST'', url: ''http://example.com'', headers: { ''Content-Type'': ''application/x-www-form-urlencoded'' }, data: $httpParamSerializer(formDataObj) }; $http(req);


Actualmente estoy usando la siguiente solución que found en el grupo de Google AngularJS.

$http .post(''/echo/json/'', ''json='' + encodeURIComponent(angular.toJson(data)), { headers: { ''Content-Type'': ''application/x-www-form-urlencoded; charset=UTF-8'' } }).success(function(data) { $scope.data = data; });

Tenga en cuenta que si está usando PHP, necesitará usar algo como la Request::createFromGlobals() del componente HTTP de Symfony 2 Request::createFromGlobals() para leer esto, ya que $ _POST no se cargará automáticamente con él.


AngularJS lo está haciendo bien al hacer el siguiente tipo de contenido dentro del encabezado de solicitud http:

Content-Type: application/json

Si va con php como yo, o incluso con Symfony2, simplemente puede ampliar la compatibilidad de su servidor para el estándar json como se describe aquí: http://silex.sensiolabs.org/doc/cookbook/json_request_body.html

La forma Symfony2 (por ejemplo, dentro de tu DefaultController):

$request = $this->getRequest(); if (0 === strpos($request->headers->get(''Content-Type''), ''application/json'')) { $data = json_decode($request->getContent(), true); $request->request->replace(is_array($data) ? $data : array()); } var_dump($request->request->all());

La ventaja sería que no necesita usar jQuery param y podría usar AngularJS su forma nativa de hacer tales solicitudes.


Como solución alternativa, simplemente puede hacer que el código que recibe el POST responda a los datos de la aplicación / json. Para PHP, agregué el siguiente código, permitiéndome POST en formato JSON o codificado.

//handles JSON posted arguments and stuffs them into $_POST //angular''s $http makes JSON posts (not normal "form encoded") $content_type_args = explode('';'', $_SERVER[''CONTENT_TYPE'']); //parse content_type string if ($content_type_args[0] == ''application/json'') $_POST = json_decode(file_get_contents(''php://input''),true); //now continue to reference $_POST vars as usual


Crear un servicio de adaptador para la publicación:

services.service(''Http'', function ($http) { var self = this this.post = function (url, data) { return $http({ method: ''POST'', url: url, data: $.param(data), headers: {''Content-Type'': ''application/x-www-form-urlencoded''} }) } })

Úsalo en tus controladores o lo que sea:

ctrls.controller(''PersonCtrl'', function (Http /* our service */) { var self = this self.user = {name: "Ozgur", eMail: null} self.register = function () { Http.post(''/user/register'', self.user).then(function (r) { //response console.log(r) }) } })


En la configuración de su aplicación -

$httpProvider.defaults.transformRequest = function (data) { if (data === undefined) return data; var clonedData = $.extend(true, {}, data); for (var property in clonedData) if (property.substr(0, 1) == ''$'') delete clonedData[property]; return $.param(clonedData); };

Con su solicitud de recursos -

headers: { ''Content-Type'': ''application/x-www-form-urlencoded'' }


Esta no es una respuesta directa, sino una dirección de diseño ligeramente diferente:

No publique los datos como un formulario, sino como un objeto JSON que se asignará directamente al objeto del lado del servidor, o use la variable de ruta de estilo REST

Ahora sé que ninguna de las opciones podría ser adecuada en su caso, ya que está intentando pasar una clave XSRF. Mapearlo en una variable de ruta como esta es un diseño terrible:

http://www.someexample.com/xsrf/{xsrfKey}

Porque por naturaleza, también querría pasar la clave xsrf a otra ruta, /login , /book-appointment etc. y no quiere desordenar su bonita URL.

Interesantemente, agregarlo como un campo de objeto tampoco es apropiado, porque ahora en cada uno de los objetos json que pasa al servidor tiene que agregar el campo

{ appointmentId : 23, name : ''Joe Citizen'', xsrf : ''...'' }

Ciertamente, no desea agregar otro campo en su clase del lado del servidor que no tenga una asociación semántica directa con el objeto de dominio.

En mi opinión, la mejor manera de pasar su clave xsrf es a través de un encabezado HTTP. Muchas bibliotecas de marco web del lado del servidor de protección xsrf admiten esto Por ejemplo, en Java Spring, puede pasarlo usando el encabezado X-CSRF-TOKEN .

La excelente capacidad de Angular para vincular el objeto JS al objeto UI significa que podemos deshacernos de la práctica de publicar el formulario todos juntos y, en su lugar, publicar JSON. JSON puede ser fácilmente serializado en objetos del lado del servidor y soportar estructuras de datos complejas como mapas, matrices, objetos anidados, etc.

¿Cómo se publica la matriz en una carga útil de formulario? Tal vez así:

shopLocation=downtown&daysOpen=Monday&daysOpen=Tuesday&daysOpen=Wednesday

o esto:

shopLocation=downtwon&daysOpen=Monday,Tuesday,Wednesday

Ambos son de diseño pobre ..


Estas respuestas parecen una exageración insana, a veces, simple es simplemente mejor:

$http.post(loginUrl, "userName=" + encodeURIComponent(email) + "&password=" + encodeURIComponent(password) + "&grant_type=password" ).success(function (data) { //...


Esto es lo que estoy haciendo para mi necesidad, donde necesito enviar los datos de inicio de sesión a la API como datos de formulario y el objeto Javascript (userData) se convierte automáticamente a datos codificados en URL

var deferred = $q.defer(); $http({ method: ''POST'', url: apiserver + ''/authenticate'', headers: { ''Content-Type'': ''application/x-www-form-urlencoded'' }, transformRequest: function (obj) { var str = []; for (var p in obj) str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); return str.join("&"); }, data: userData }).success(function (response) { //logics deferred.resolve(response); }).error(function (err, status) { deferred.reject(err); });

Así es como mi Userdata es

var userData = { grant_type: ''password'', username: loginData.userName, password: loginData.password }


Hay un tutorial realmente bueno que repasa esto y otras cosas relacionadas: Envío de formularios AJAX: The AngularJS Way .

Básicamente, debe configurar el encabezado de la solicitud POST para indicar que está enviando datos de formulario como una cadena codificada de URL y configurar los datos para que se envíen en el mismo formato

$http({ method : ''POST'', url : ''url'', data : $.param(xsrf), // pass in data as strings headers : { ''Content-Type'': ''application/x-www-form-urlencoded'' } // set the headers so angular passing info as form data (not request payload) });

Tenga en cuenta que la función de ayuda param () de jQuery se usa aquí para serializar los datos en una cadena, pero puede hacerlo manualmente también si no usa jQuery.


La continua confusión en torno a este tema me inspiró a escribir una publicación de blog al respecto. La solución que propongo en esta publicación es mejor que su mejor solución actual, ya que no le restringe la parametrización de su objeto de datos para llamadas de servicio de $ http; es decir, con mi solución, simplemente puede continuar pasando los objetos de datos reales a $ http.post (), etc. y aún así lograr el resultado deseado.

Además, la respuesta más valorada se basa en la inclusión de jQuery completo en la página para la función $ .param (), mientras que mi solución es jQuery agnóstica, lista para AngularJS puro.

http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

Espero que esto ayude.


La siguiente línea debe agregarse al objeto $ http que se pasa:

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

Y los datos pasados ​​deben convertirse en una cadena codificada en URL:

> $.param({fkey: "key"}) ''fkey=key''

Así que tienes algo como:

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

Desde: https://groups.google.com/forum/#!msg/angular/5nAedJ1LyO0/4Vj_72EZcDsJ

ACTUALIZAR

Para usar los nuevos servicios agregados con AngularJS V1.4, vea

  • Variables de codificación de URL que utilizan solo servicios de AngularJS

Lo único que tienes que cambiar es usar la propiedad "params" en lugar de "datos" cuando crees tu objeto $ http:

$http({ method: ''POST'', url: serviceUrl + ''/ClientUpdate'', params: { LangUserId: userId, clientJSON: clients[i] }, })

En el ejemplo anterior, los clientes [i] son ​​solo objetos JSON (no serializados de ninguna manera). Si usa "parámetros" en lugar de "datos", el objeto serializará el objeto usando $ httpParamSerializer: https://docs.angularjs.org/api/ng/service/ $ httpParamSerializer


Para usuarios de Symfony2:

Si no quieres cambiar nada en tu javascript para que esto funcione, puedes hacer estas modificaciones en tu aplicación de Symfony:

Crea una clase que amplíe la clase Symfony / Component / HttpFoundation / Request:

<?php namespace Acme/Test/MyRequest; use Symfony/Component/HttpFoundation/Request; use Symfony/Component/HttpFoundation/ParameterBag; class MyRequest extends Request{ /** * Override and extend the createFromGlobals function. * * * * @return Request A new request * * @api */ public static function createFromGlobals() { // Get what we would get from the parent $request = parent::createFromGlobals(); // Add the handling for ''application/json'' content type. if(0 === strpos($request->headers->get(''CONTENT_TYPE''), ''application/json'')){ // The json is in the content $cont = $request->getContent(); $json = json_decode($cont); // ParameterBag must be an Array. if(is_object($json)) { $json = (array) $json; } $request->request = new ParameterBag($json); } return $request; } }

Ahora use su clase en app_dev.php (o cualquier archivo de índice que use)

// web/app_dev.php $kernel = new AppKernel(''dev'', true); // $kernel->loadClassCache(); $request = ForumBundleRequest::createFromGlobals(); // use your class instead // $request = Request::createFromGlobals(); $response = $kernel->handle($request); $response->send(); $kernel->terminate($request, $response);


Puedes definir el comportamiento globalmente:

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

Así que no tienes que redefinir cada vez que:

$http.post("/handle/post", { foo: "FOO", bar: "BAR" }).success(function (data, status, headers, config) { // TODO }).error(function (data, status, headers, config) { // TODO });


Puedes probar con la siguiente solución

$http({ method: ''POST'', url: url-post, data: data-post-object-json, headers: {''Content-Type'': ''application/x-www-form-urlencoded''}, transformRequest: function(obj) { var str = []; for (var key in obj) { if (obj[key] instanceof Array) { for(var idx in obj[key]){ var subObj = obj[key][idx]; for(var subKey in subObj){ str.push(encodeURIComponent(key) + "[" + idx + "][" + encodeURIComponent(subKey) + "]=" + encodeURIComponent(subObj[subKey])); } } } else { str.push(encodeURIComponent(key) + "=" + encodeURIComponent(obj[key])); } } return str.join("&"); } }).success(function(response) { /* Do something */ });


Respuesta completa (desde angular 1.4). Debe incluir la dependencia $ httpParamSerializer

var res = $resource(serverUrl + ''Token'', { }, { save: { method: ''POST'', headers: { ''Content-Type'': ''application/x-www-form-urlencoded'' } } }); res.save({ }, $httpParamSerializer({ param1: ''sdsd'', param2: ''sdsd'' }), function (response) { }, function (error) { });


Si no desea utilizar jQuery en la solución, puede intentar esto. Solución atrapada desde aquí https://.com/a/1714899/1784301

$http({ method: ''POST'', url: url, headers: {''Content-Type'': ''application/x-www-form-urlencoded''}, transformRequest: function(obj) { var str = []; for(var p in obj) str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); return str.join("&"); }, data: xsrf }).success(function () {});


Simplemente configurar Contenido-Tipo no es suficiente, url codificar datos de formulario antes de enviar. $http.post(url, jQuery.param(data))


Tomé algunas de las otras respuestas e hice algo un poco más limpio, puse esta llamada .config() al final de angular.module en tu app.js:

.config([''$httpProvider'', function ($httpProvider) { // Intercept POST requests, convert to standard form encoding $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; $httpProvider.defaults.transformRequest.unshift(function (data, headersGetter) { var key, result = []; if (typeof data === "string") return data; for (key in data) { if (data.hasOwnProperty(key)) result.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key])); } return result.join("&"); }); }]);


Use el servicio AngularJS $http y use su método de post o configure la función $http .