programing

AngularJS POST 실패 : 프리 플라이트에 대한 응답에 잘못된 HTTP 상태 코드 404가 있습니다.

nasanasas 2020. 12. 12. 11:05
반응형

AngularJS POST 실패 : 프리 플라이트에 대한 응답에 잘못된 HTTP 상태 코드 404가 있습니다.


나는 이와 같은 많은 질문이 있다는 것을 알고 있지만 내 문제를 해결 한 적이 없습니다. 이미 최소 3 개의 마이크로 프레임 워크를 사용했습니다. 모두 간단한 POST를 수행하는 데 실패하여 데이터를 다시 반환해야합니다.

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

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

CORS를 활성화했으며 GET 요청이 작동합니다. html은 서버에서 보낸 JSON 콘텐츠로 업데이트됩니다. 그러나 나는

XMLHttpRequest는 http : // localhost : 8080 / server.php / post를 로드 할 수 없습니다 . 프리 플라이트에 대한 응답에 잘못된 HTTP 상태 코드 404가 있습니다.

POST를 사용하려고 할 때마다. 왜?

편집 : Pointy가 요청한 req / res req / res 헤더


좋아, 내가 이것을 어떻게 알아 냈는지 여기에 있습니다. 그것은 모두 CORS 정책과 관련이 있습니다. POST 요청 전에 Chrome은 실제 요청 전에 서버에서 처리하고 확인해야하는 프리 플라이트 OPTIONS 요청을 수행했습니다. 이제 이것은 내가 그렇게 간단한 서버에 원했던 것이 아닙니다. 따라서 클라이언트 측 헤더를 재설정하면 프리 플라이트가 방지됩니다.

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

이제 브라우저가 POST를 직접 보냅니다. 이것이 많은 사람들에게 도움이되기를 바랍니다. 내 진짜 문제는 CORS를 충분히 이해하지 못했습니다.

훌륭한 설명 링크 : http://www.html5rocks.com/en/tutorials/cors/

나에게 길을 보여준 이 대답에 대한 찬사 .


CORS를 활성화 Access-Control-Allow-Origin : *하고 서버에서 활성화 했습니다. 그래도 GET메서드가 작동하고 POST메서드가 작동하지 않으면 문제 Content-Typedata문제 때문일 수 있습니다 .

첫 번째 AngularJSContent-Type: application/json일부 웹 서버 (특히 PHP)에서 기본적으로 직렬화되지 않은 데이터를 사용하여 전송합니다 . 그들을 위해 우리는 데이터를 다음과 같이 전송해야합니다.Content-Type: x-www-form-urlencoded

예 :-

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

참고 : 내가 사용하고 $.params사용하여 데이터를 직렬화 Content-Type: x-www-form-urlencoded. 또는 다음 자바 스크립트 함수를 사용할 수 있습니다.

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

요청이 형식 의 POST 데이터 만 가져 params({ 'username': $scope.username, 'Password': $scope.Password })오므로 직렬화하는 데 사용 합니다 .Content-Type: x-www-form-urlencodedusername=john&Password=12345


Node.js 앱의 경우 모든 경로를 등록하기 전에 server.js 파일에 아래 코드를 넣었습니다. 모든 응답에 대한 헤더를 설정합니다. 또한 비행 전 "OPTIONS"호출 인 경우 응답을 정상적으로 종료하고 실제 비즈니스 논리 경로를 통해 "연결"(단어입니까?)없이 클라이언트에 즉시 비행 전 응답을 다시 보냅니다. 다음은 내 server.js 파일입니다. 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);

참고 URL : https://stackoverflow.com/questions/33660712/angularjs-post-fails-response-for-preflight-has-invalid-http-status-code-404

반응형