javascript - send - post method angularjs




Falha no POST do AngularJS: a resposta para a comprovação possui o código de status HTTP inválido 404 (2)

Sei que há muitas perguntas como essa, mas nenhuma que eu tenha visto resolveu meu problema. Eu já usei pelo menos três microframework. Todos eles falham ao executar um POST simples, que deve retornar os dados:

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

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

Ativei o CORS e as solicitações GET funcionam. O html é atualizado com o conteúdo JSON enviado pelo servidor. No entanto, recebo um

O XMLHttpRequest não pode carregar http://localhost:8080/server.php/post . A resposta para a comprovação possui o código de status HTTP 404 inválido

Sempre que tento usar o POST. Por quê?

EDIT: O req / res, conforme solicitado por Pointy


Ok, então aqui está como eu descobri isso. Tudo tem a ver com a política do CORS. Antes da solicitação do POST, o Chrome fazia uma solicitação de OPTION de comprovação, que deveria ser tratada e reconhecida pelo servidor antes da solicitação real. Agora, isso não é realmente o que eu queria para um servidor tão simples. Portanto, redefinir os cabeçalhos do lado do cliente impede a comprovação:

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

O navegador agora enviará um POST diretamente. Espero que isso ajude muita gente por aí ... Meu verdadeiro problema não era entender o CORS o suficiente.

Link para uma ótima explicação: http://www.html5rocks.com/en/tutorials/cors/

Parabéns a esta resposta por me mostrar o caminho.


Para um aplicativo Node.js, no arquivo server.js antes de registrar todas as minhas próprias rotas, coloquei o código abaixo. Ele define os cabeçalhos para todas as respostas. Ele também encerra a resposta normalmente se for uma chamada de "OPÇÕES" antes do voo e envia imediatamente a resposta antes do voo de volta ao cliente sem "seguir" (isso é uma palavra?) Pelas rotas reais da lógica de negócios. Aqui está o meu arquivo server.js. Seções relevantes destacadas para uso no .

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




cors