with example javascript php angularjs ajax cors

javascript - example - ng-src



AngularJS POST falla: la respuesta para la verificación previa tiene un código de estado HTTP 404 no válido (3)

Ha habilitado CORS y Access-Control-Allow-Origin : * en el servidor. Si todavía obtiene el método GET funcionando y el método POST no funciona, puede deberse al problema de Content-Type y de data .

Primero AngularJS transmite datos usando Content-Type: application/json que no está serializado de forma nativa por algunos de los servidores web (especialmente PHP). Para ellos tenemos que transmitir los datos como Content-Type: x-www-form-urlencoded

Ejemplo:

$scope.formLoginPost = function () { $http({ url: url, method: "POST", data: $.param({ ''username'': $scope.username, ''Password'': $scope.Password }), headers: { ''Content-Type'': ''application/x-www-form-urlencoded'' } }).then(function (response) { // success console.log(''success''); console.log("then : " + JSON.stringify(response)); }, function (response) { // optional // failed console.log(''failed''); console.log(JSON.stringify(response)); }); };

Nota: Estoy usando $.params para serializar los datos para usar Content-Type: x-www-form-urlencoded . Alternativamente, puede usar la siguiente función de JavaScript

function params(obj){ var str = ""; for (var key in obj) { if (str != "") { str += "&"; } str += key + "=" + encodeURIComponent(obj[key]); } return str; }

y use params({ ''username'': $scope.username, ''Password'': $scope.Password }) para serializarlo como el tipo de Content-Type: x-www-form-urlencoded solicitudes Content-Type: x-www-form-urlencoded solo obtienen los datos POST en username=john&Password=12345 formulario.

Sé que hay muchas preguntas como esta, pero ninguna que haya visto ha solucionado mi problema. Ya he usado al menos 3 microframeworks. Todos ellos fallan al hacer una POST simple, que debería devolver los datos:

El cliente angularJS:

var app = angular.module(''client'', []); app.config(function ($httpProvider) { //uncommenting the following line makes GET requests fail as well //$httpProvider.defaults.headers.common[''Access-Control-Allow-Headers''] = ''*''; delete $httpProvider.defaults.headers.common[''X-Requested-With'']; }); app.controller(''MainCtrl'', function($scope, $http) { var baseUrl = ''http://localhost:8080/server.php'' $scope.response = ''Response goes here''; $scope.sendRequest = function() { $http({ method: ''GET'', url: baseUrl + ''/get'' }).then(function successCallback(response) { $scope.response = response.data.response; }, function errorCallback(response) { }); }; $scope.sendPost = function() { $http.post(baseUrl + ''/post'', {post: ''data from client'', withCredentials: true }) .success(function(data, status, headers, config) { console.log(status); }) .error(function(data, status, headers, config) { console.log(''FAILED''); }); } });

El servidor SlimPHP:

<?php require ''vendor/autoload.php''; $app = new /Slim/Slim(); $app->response()->headers->set(''Access-Control-Allow-Headers'', ''Content-Type''); $app->response()->headers->set(''Content-Type'', ''application/json''); $app->response()->headers->set(''Access-Control-Allow-Methods'', ''GET, POST, OPTIONS''); $app->response()->headers->set(''Access-Control-Allow-Origin'', ''*''); $array = ["response" => "Hello World!"]; $app->get(''/get'', function() use($array) { $app = /Slim/Slim::getInstance(); $app->response->setStatus(200); echo json_encode($array); }); $app->post(''/post'', function() { $app = /Slim/Slim::getInstance(); $allPostVars = $app->request->post(); $dataFromClient = $allPostVars[''post'']; $app->response->setStatus(200); echo json_encode($dataFromClient); }); $app->run();

He habilitado CORS y las solicitudes GET funcionan. El html se actualiza con el contenido JSON enviado por el servidor. Sin embargo me sale un

XMLHttpRequest no puede cargar http://localhost:8080/server.php/post . La respuesta para la verificación previa tiene un código de estado HTTP 404 no válido

Cada vez que trato de usar POST. ¿Por qué?

EDITAR: Los requisitos / res solicitados por Pointy


Ok, así es como descubrí esto. Todo tiene que ver con la política de CORS. Antes de la solicitud POST, Chrome estaba haciendo una solicitud OPTIONS de verificación previa, que el servidor debe manejar y reconocer antes de la solicitud real. Ahora bien, esto no es lo que quería para un servidor tan simple. Por lo tanto, restablecer los encabezados del lado del cliente evita la verificación previa:

app.config(function ($httpProvider) { $httpProvider.defaults.headers.common = {}; $httpProvider.defaults.headers.post = {}; $httpProvider.defaults.headers.put = {}; $httpProvider.defaults.headers.patch = {}; });

El navegador ahora enviará una POST directamente. Espero que esto ayude a mucha gente ... Mi verdadero problema era no entender CORS lo suficiente.

Enlace a una gran explicación: http://www.html5rocks.com/en/tutorials/cors/

Felicitaciones a esta respuesta por mostrarme el camino.


Para una aplicación Node.js, en el archivo server.js antes de registrar todas mis rutas, pongo el código a continuación. Establece los encabezados para todas las respuestas. También finaliza la respuesta con gracia si se trata de una llamada de "OPCIONES" previa al vuelo e inmediatamente envía la respuesta previa al vuelo de regreso al cliente sin "nexting" (¿es una palabra?) A través de las rutas lógicas comerciales reales. Aquí está mi archivo server.js. Secciones relevantes resaltadas para el uso de .

// server.js // ================== // BASE SETUP // import the packages we need var express = require(''express''); var app = express(); var bodyParser = require(''body-parser''); var morgan = require(''morgan''); var jwt = require(''jsonwebtoken''); // used to create, sign, and verify tokens // ==================================================== // configure app to use bodyParser() // this will let us get the data from a POST app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); // Logger app.use(morgan(''dev'')); // ------------------------------------------------------------- // -- PAY ATTENTION TO THIS NEXT SECTION !!!!! // ------------------------------------------------------------- //Set CORS header and intercept "OPTIONS" preflight call from AngularJS var allowCrossDomain = function(req, res, next) { res.header(''Access-Control-Allow-Origin'', ''*''); res.header(''Access-Control-Allow-Methods'', ''GET,PUT,POST,DELETE''); res.header(''Access-Control-Allow-Headers'', ''Content-Type''); if (req.method === "OPTIONS") res.send(200); else next(); } // ------------------------------------------------------------- // -- END OF THIS SECTION, ONE MORE SECTION BELOW // ------------------------------------------------------------- // ================================================= // ROUTES FOR OUR API var route1 = require("./routes/route1"); var route2 = require("./routes/route2"); var error404 = require("./routes/error404"); // ====================================================== // REGISTER OUR ROUTES with app // ------------------------------------------------------------- // -- PAY ATTENTION TO THIS NEXT SECTION !!!!! // ------------------------------------------------------------- app.use(allowCrossDomain); // ------------------------------------------------------------- // -- OK THAT IS THE LAST THING. // ------------------------------------------------------------- app.use("/api/v1/route1/", route1); app.use("/api/v1/route2/", route2); app.use(''/'', error404); // ================= // START THE SERVER var port = process.env.PORT || 8080; // set our port app.listen(port); console.log(''API Active on port '' + port);