问题描述
我知道有很多这样的问题,但我所见过的都没有解决我的问题.我已经使用了至少 3 个微框架.所有这些都无法执行简单的 POST,这应该返回数据:
angularJS 客户端:
var app = angular.module('client', []);app.config(function ($httpProvider) {//取消注释以下行也会使 GET 请求失败//$httpProvider.defaults.headers.common['Access-Control-Allow-Headers'] = '*';删除 $httpProvider.defaults.headers.common['X-Requested-With'];});app.controller('MainCtrl', function($scope, $http) {var baseUrl = 'http://localhost:8080/server.php'$scope.response = '响应到这里';$scope.sendRequest = function() {$http({方法:'获取',网址:baseUrl + '/get'}).then(函数successCallback(响应){$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) {控制台日志(状态);}).error(function(data, status, headers, config) {console.log('失败');});}});
SlimPHP 服务器:
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 = [响应" =>你好,世界!"];$app->get('/get', function() use($array) {$app = \Slim\Slim::getInstance();$app->response->setStatus(200);回声 json_encode($array);});$app->post('/post', function() {$app = \Slim\Slim::getInstance();$allPostVars = $app->request->post();$dataFromClient = $allPostVars['post'];$app->response->setStatus(200);回声 json_encode($dataFromClient);});$app->run();
我已启用 CORS,并且 GET 请求有效.html 使用服务器发送的 JSON 内容进行更新.但是我得到一个
XMLHttpRequest 无法加载
已经过去了很多年,但我觉得有必要进一步对此发表评论.现在我实际上是一名开发人员.对后端的请求通常使用一个令牌进行身份验证,您的框架将接收并处理该令牌;这就是所缺少的.我实际上完全不确定这个解决方案是如何工作的.
原文:
好的,这就是我是怎么想出来的.这一切都与 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/教程/cors/
感谢这个答案为我指明了道路.
I know there are a lot of questions like this, but none I've seen have fixed my issue. I've used at least 3 microframeworks already. All of them fail at doing a simple POST, which should return the data back:
The 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');
});
}
});
The 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 enabled CORS, and GET requests work. The html updates with the JSON content sent by the server. However I get a
XMLHttpRequest cannot load http://localhost:8080/server.php/post. Response for preflight has invalid HTTP status code 404
Everytime I try to use POST. Why?
EDIT: The req/res as requested by Pointy
EDIT:
It's been years, but I feel obliged to comment on this further. Now I actually am a developer. Requests to your back-end are usually authenticated with a token which your frameworks will pick up and handle; and this is what was missing. I'm actually not sure how this solution worked at all.
ORIGINAL:
Ok so here's how I figured this out.It all has to do with CORS policy. Before the POST request, Chrome was doing a preflight OPTIONS request, which should be handled and acknowledged by the server prior to the actual request. Now this is really not what I wanted for such a simple server. Hence, resetting the headers client side prevents the preflight:
app.config(function ($httpProvider) {
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
});
The browser will now send a POST directly. Hope this helps a lot of folks out there... My real problem was not understanding CORS enough.
Link to a great explanation: http://www.html5rocks.com/en/tutorials/cors/
Kudos to this answer for showing me the way.
这篇关于AngularJS POST 失败:预检响应具有无效的 HTTP 状态代码 404的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!