简体   繁体   English

无法从角度调用Express Rest API

[英]Failing to call express rest api from angular

I'm following this tutorial on building a Single Page Application with express and AngularJS on nodejs. 我正在按照本教程在nodejs上使用express和AngularJS构建单页应用程序。

I'm Trying to call the web api from the angular module, but I keep receiving the entire page html content, instead of the actual value 我正在尝试从angular模块调用Web api,但我一直收到整个页面的html内容,而不是实际值

<!-- index.html -->
<!doctype html>

<!-- ASSIGN OUR ANGULAR MODULE -->
<html ng-app="scotchTodo">
<head>
    <!-- META -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1"><!-- Optimize mobile viewport -->

    <title>Node/Angular Todo App</title>

    <!-- SCROLLS -->
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"><!-- load bootstrap -->
    <style>
        html                    { overflow-y:scroll; }
        body                    { padding-top:50px; }
        #todo-list              { margin-bottom:30px; }
    </style>

    <!-- SPELLS -->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script><!-- load jquery -->
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script><!-- load angular -->
    <script src="core.js"></script>

</head>
<!-- SET THE CONTROLLER AND GET ALL TODOS -->
<body ng-controller="mainController">
<div class="container">

    <!-- HEADER AND TODO COUNT -->
    <div class="jumbotron text-center">
        <h1>I'm a Todo-aholic <span class="label label-info">{{ todos.length }}</span></h1>
    </div>

    <!-- TODO LIST -->
    <div id="todo-list" class="row">
        <div class="col-sm-4 col-sm-offset-4">

            <!-- LOOP OVER THE TODOS IN $scope.todos -->
            <div class="checkbox" ng-repeat="todo in todos">
                <label>
                    <input type="checkbox" ng-click="deleteTodo(todo._id)"> {{ todo.text }}
                </label>
            </div>

        </div>
    </div>

    <!-- FORM TO CREATE TODOS -->
    <div id="todo-form" class="row">
        <div class="col-sm-8 col-sm-offset-2 text-center">
            <form>
                <div class="form-group">

                    <!-- BIND THIS VALUE TO formData.text IN ANGULAR -->
                    <input type="text" class="form-control input-lg text-center" placeholder="I want to buy a puppy that will love me forever" ng-model="formData.text">
                </div>

                <!-- createToDo() WILL CREATE NEW TODOS -->
                <button type="submit" class="btn btn-primary btn-lg" ng-click="createTodo()">Add</button>
            </form>
        </div>
    </div>

</div>

</body>
</html>

-- -

// public/core.js
var scotchTodo = angular.module('scotchTodo', []);

function mainController($scope, $http) {
    $scope.formData = {};

    // when landing on the page, get all todos and show them
    $http.get('/api/something')
        .success(function(data) {
            $scope.todos = data;
            console.log(data);
            alert(data)
        })
        .error(function(data) {
            console.log('Error: ' + data);
        });

    // when submitting the add form, send the text to the node API
    $scope.createTodo = function() {
        $http.post('/api/todos', $scope.formData)
            .success(function(data) {
                $scope.formData = {}; // clear the form so our user is ready to enter another
                $scope.todos = data;
                console.log(data);
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
    };

    // delete a todo after checking it
    $scope.deleteTodo = function(id) {
        $http.delete('/api/todos/' + id)
            .success(function(data) {
                $scope.todos = data;
                console.log(data);
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
    };
}

-- -

//server.js
// set up ========================
var express = require('express');
var app = express();                                // create our app w/ express

// configuration =================

app.configure(function () {
    app.use(express.static(__dirname + '/public'));         // set the static files location /public/img will be /img for users
    app.use(express.logger('dev'));                         // log every request to the console
    app.use(express.bodyParser());                          // pull information from html in POST
    app.use(express.methodOverride());                      // simulate DELETE and PUT
});

// listen (start app with node server.js) ======================================
app.listen(8080);
console.log("App listening on port 8080");

// application
app.get('*', function (req, res) {
    res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});

// api routes

app.get('/api/something',function(req,res){
    res.json({text: "1"});
});

// get all todos
app.get('/api/todos', function (req, res) {
    console.log("api/todos")
    var todos = [];
    res.json(todos); // return all todos in JSON format
});

// create todo and send back all todos after creation
app.post('/api/todos', function (req, res) {
    // create a todo, information comes from AJAX request from Angular
    Todo.create({
        text: req.body.text,
        done: false
    }, function (err, todo) {
        if (err)
            res.send(err);

        // get and return all the todos after you create another
        Todo.find(function (err, todos) {
            if (err)
                res.send(err)
            res.json(todos);
        });
    });

});

// delete a todo
app.delete('/api/todos/:todo_id', function (req, res) {
    Todo.remove({
        _id: req.params.todo_id
    }, function (err, todo) {
        if (err)
            res.send(err);

        // get and return all the todos after you create another
        Todo.find(function (err, todos) {
            if (err)
                res.send(err)
            res.json(todos);
        });
    });
});

But all I get instead of the value I tried to pass is the full html: 但是我得到的而不是我尝试传递的值是完整的html: chrome开发者控制台

This route... 这条路线...

// application
app.get('*', function (req, res) {
    res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});

... is responding to all GET requests because it comes before the /api/something route. ...正在响应所有GET请求,因为它在/api/something路由之前。 Either swap it with the /api/something route... 要么用/api/something路由交换它...

app.get('/api/something',function(req,res){
    res.json({text: "1"});
});

app.get('*', function (req, res) {
    res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});

Or don't use a wildcard... 或者不要使用通配符...

app.get('/', function (req, res) {
    res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});

You just need to change your server code so that index.html is only returned when a get request is sent to '/'. 您只需要更改服务器代码,以使index.html仅在将get请求发送到'/'时才返回。 You currently have it set up to return index.html on any get request that matches '*'...so everything. 当前,您已将其设置为在与“ *”匹配的任何get请求上返回index.html ...因此所有内容。

app.get('/', function (req, res) {
    res.sendfile('./public/index.html');
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM