POST carbon error: preflight response has an invalid HTTP 404 status code

I know that there are many such questions, but none of them fixed my problem. I have already used at least 3 microcards. All of them cannot perform a simple POST, which should return data:

AngularJS Client:

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

SlimPHP Server:

 <?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(); 

I have included CORS and the GET requests work. Html updates the JSON content sent by the server. However i get

XMLHttpRequest cannot load http: // localhost: 8080 / server.php / post . The response to the pre-flight date has an invalid HTTP status code 404

Every time I try to use POST. Why?

EDIT: req / res at Pointy's request req / res headers

+47
javascript angularjs ajax php cors
Nov 11 '15 at 22:02
source share
3 answers

Well, that’s how I understood it. All this is connected with the KORS policy. Before the POST request, Chrome made an OPTIONS request before sending, which must be processed and confirmed by the server before the actual request. Now this is really not what I wanted for such a simple server. Therefore, resetting the client portion of the headers prevents a pre-flight check:

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

Now the browser will send POST directly. Hope this helps a lot of people ... My real problem was that I didn't understand CORS enough.

Link to a wonderful explanation: http://www.html5rocks.com/en/tutorials/cors/

Kudos to this answer for showing me the way.

+79
Nov 12
source

You have enabled CORS and enabled Access-Control-Allow-Origin : * on the server. If you still work with GET , and the POST method does not work, this may be due to a problem with the Content-Type and data problem.

The first AngularJS transfers data using Content-Type: application/json , which is not serialized initially by some web servers (in particular PHP). For them, we must pass the data as Content-Type: x-www-form-urlencoded

Example: -

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

Note. I use $.params to serialize data to use Content-Type: x-www-form-urlencoded . Alternatively you can use the following javascript function

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

and use params({ 'username': $scope.username, 'Password': $scope.Password }) for serialization, as Content-Type: x-www-form-urlencoded requests only receive POST data in the form username=john&Password=12345 .

+5
Jun 03 '17 at 11:37 on
source

For the Node.js application, in the server.js file, before I register all my own routes, I put the code below. He sets the headers for all the answers. It also completes the answer perfectly if it is a pre-flight call of “OPTIONS” and immediately sends the answer before the flight back to the client without the “next” (is this a word?) Down the actual business logic routes. Here is my server.js file. The relevant sections are highlighted for use by Stackoverflow.

 // 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')); // ------------------------------------------------------------- // STACKOVERFLOW -- 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(); } // ------------------------------------------------------------- // STACKOVERFLOW -- 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 // ------------------------------------------------------------- // STACKOVERFLOW -- PAY ATTENTION TO THIS NEXT SECTION !!!!! // ------------------------------------------------------------- app.use(allowCrossDomain); // ------------------------------------------------------------- // STACKOVERFLOW -- 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); 
+2
May 25 '17 at 10:37 p.m.
source



All Articles