AngularJS和ExpressJS:如何读取$ http.put()发送的内容

时间:2015-08-21 08:12:36

标签: angularjs node.js express

我遇到angularJS应用程序的问题,它将回调发送到nodejs服务器。当我使用POST或GET方法时,一切正常,但是当我发送PUT请求时,我收到错误。

如果我从curl呼叫服务器,它运行正常;当我使用PUT方法从angularJS调用一些远程服务器时,它也可以正常工作。所以问题在于我的localhost上angularJS和nodejs之间的合作,但我还没有弄明白。

我的角度方法,调用本地nodejs服务器:

 $http({
   method  :'PUT',
     url:'http://127.0.0.1:3000/s',
     data: $.param({"test":true, _method: 'PUT'}),
     headers :{'Content-Type':'application/x-www-form-urlencoded'}
        }).success(function(data, status, headers, config) {
            alert('OK');
        }).error(function(data, status, headers, config) {
            alert('error');
        }).catch(function(error){
            alert('catch' + JSON.stringify(error));
        });

我的nodejs文件:

var express        =    require("express");
var mysql          =    require('mysql');
var bodyParser     =    require('body-parser')
var methodOverride =    require('method-override');
var app            =    express();

//use body parser to get json
app.use(bodyParser.json())
// for parsing application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// allow PUT from browser
app.use(methodOverride('_method'));

app.put('/s', function(req, res){
  console.log('OK');
  //handle_database_put(req, res);
  res.set('Access-Control-Allow-Origin', '*');
  res.set('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
  res.send('PUT OK');
});

app.listen(3000);

编辑以下是Angular应用中的错误消息。服务器永远不会打印OK,因为它应该

{"data":null,"status":0,"config":{"method":"PUT","transformRequest":[null],"transformResponse":[null],"url":"http://127.0.0.1:3000/s","data":"test=true&_method=PUT","headers":{"Content-Type":"application/x-www-form-urlencoded","Accept":"application/json, text/plain, */*"}},"statusText":""}

编辑2 :我刚刚注意到,该请求未被识别为PUT,而是OPTIONS

3 个答案:

答案 0 :(得分:2)

试试这个

$http({
   method  :'PUT',
     url:'http://127.0.0.1:3000/s',
     params: {"test":true, _method: 'PUT'},
     headers :{'Content-Type':'application/json'}
        }).success(function(data, status, headers, config) {
            alert('OK');
        }).error(function(data, status, headers, config) {
            alert('error');
        }).catch(function(error){
            alert('catch' + JSON.stringify(error));
        });

答案 1 :(得分:1)

我终于找到了问题:

发生的情况是,浏览器发出预检OPTIONS HTTP请求,如果它从服务器接收状态200,则进行到原始PUT呼叫。

在ExpressJS服务器上,进行了以下配置,并且AngularJS的PUT请求现在正在使用PUT请求正确发送和接收数据:

// apply this rule to all requests accessing any URL/URI
app.all('*', function(req, res, next) {
    // add details of what is allowed in HTTP request headers to the response headers
    res.header('Access-Control-Allow-Origin', req.headers.origin);
    res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
    res.header('Access-Control-Allow-Credentials', false);
    res.header('Access-Control-Max-Age', '86400');
    res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
    // the next() function continues execution and will move onto the requested URL/URI
    next();
});

对我而言,为什么POST请求被正确处理且PUT请求不是

,这仍然是个谜。

答案 2 :(得分:0)

您的服务器"Accept":"application/json并且您要发送"Content-Type":"application/x-www-form-urlencoded",因此您必须使用'Content-Type': 'application/json'并将数据转换为json,如下所示:

function youMethod(){
            var myUrl = 'http://127.0.0.1:3000/s';

            var data = {
                test: true,
                _method: "PUT"
            };

            return $http({
                url: myUrl,
                method: 'PUT',
                data: JSON.stringify(data), 
                headers: {
                    'Content-Type': 'application/json'
                }
              }).then(youMethodComplete)
                .catch(youMethodFailed);

            function youMethodComplete(response) {
                alert('OK');
                console.log(response);
            }

            function uyouMethodFailed(response) {
                alert('ERROR');
                console.log(response);     
            }
        }

pd:我也推荐 - > don't use $http success

额外:如果您想使用"Content-Type":"application/x-www-form-urlencoded"并为此配置服务器,并且希望遵循以下语法:

function youMethod(){
                var myUrl = 'http://127.0.0.1:3000/s';

                var data = {
                    test: true,
                    _method: "PUT"
                };

                return $http({
                    url: myUrl,
                    method: 'PUT',
                    data: $httpParamSerializer(data), //remember to inject $httpParamSerializer
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    }
                  }).then(youMethodComplete)
                    .catch(youMethodFailed);

                function youMethodComplete(response) {
                    alert('OK');
                    console.log(response);
                }

                function uyouMethodFailed(response) {
                    alert('ERROR');
                    console.log(response);     
                }
            }