Статьи

Создайте приложение AngularJS с нуля, работает на Python EVE

В предыдущей части этой серии мы увидели, как начать работу с Eve , структурой API-интерфейса REST Python, и создать некоторые API. В этой части серии мы будем использовать эти API для создания приложений на основе Node.js и AngularJS .

Мы будем реализовывать функцию регистрации, используя Node.js, и добавим другие функции, вызывая API REST из AngularJS.

Для начала клонируйте исходный код предыдущего урока и запустите API.

1
git clone https://github.com/jay3dec/REST_API_EVE_Part-1

После того, как вы клонировали исходный код, убедитесь, что у вас запущен MongoDB. Перейдите в REST_API_EVE_Part-1 и запустите приложение:

1
2
cd REST_API_EVE_Part-1
python app.py

Теперь ваш API должен работать на http: // localhost: 5000 / .

Создайте папку проекта под названием AngularNodeApp . Мы будем использовать Express , минималистичную среду веб-приложений для создания приложений Node.js. Итак, давайте установим express в наш проект.

1
npm install express

После установки express создайте файл с именем app.js Внутри app.js мы создадим наше экспресс-приложение и определим маршруты для приложения.

Давайте начнем с импорта Express в app.js и создания приложения Express.

1
2
3
4
5
6
7
8
var express = require(‘express’),
    app = express();
 
app.get(‘/’,function(req,res){
    res.send(‘welcome !!’);
});
 
app.listen(3000)

Мы только что создали экспресс-приложение и определили маршрут / , который при запросе вернет welcome . Запустите сервер.

1
node app.js

Направьте ваш браузер на http: // localhost: 3000 /, и вы должны получить welcome !! сообщение welcome !! ,

Давайте создадим домашнюю страницу для нашего приложения. Перейдите в папку проекта и создайте новый каталог с именем public . Внутри public/index создайте файл с именем index.html . Добавьте следующий HTML-код в index.html .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE html>
<html lang=»en»>
 
<head>
    <title>Angular Node App</title>
 
 
    <link href=»http://getbootstrap.com/dist/css/bootstrap.min.css» rel=»stylesheet»>
 
    <link href=»http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css» rel=»stylesheet»>
 
 
</head>
 
<body>
 
    <div class=»container»>
        <div class=»header»>
            <nav>
                <ul class=»nav nav-pills pull-right»>
                    <li role=»presentation» class=»active»><a href=»#»>Home</a>
                    </li>
                    <li role=»presentation»><a href=»/signIn»>Sign In</a>
                    </li>
                    <li role=»presentation»><a href=»/signUp»>Sign Up</a>
                    </li>
                </ul>
            </nav>
            <h3 class=»text-muted»>Angular Node App</h3>
        </div>
 
        <div class=»jumbotron»>
            <h1>Angular Node App</h1>
            <p class=»lead»></p>
            <p><a class=»btn btn-lg btn-success» href=»/signUp» role=»button»>Sign up today</a>
            </p>
        </div>
 
 
 
        <footer class=»footer»>
            <p>&copy;
        </footer>
 
    </div>
</body>
 
</html>

Далее, давайте изменим существующий обработчик / request для отображения index.html . Определите путь к app.js папке в app.js

1
app.use(express.static(__dirname + ‘/public’));

Измените обработчик / request, как показано:

1
2
3
app.get(‘/’,function(req,res){
    res.sendFile(‘index.html’,{‘root’: __dirname + ‘/public/index’});
});

Сохраните изменения и перезапустите сервер. Укажите в браузере http: // localhost: 3000 /, и вы должны увидеть страницу приложения.

Домашняя страница

Затем создайте страницу с именем signin/signin.html и добавьте следующий HTML-код:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<!DOCTYPE html>
<html lang=»en»>
 
<head>
    <title>Python Flask Bucket List App</title>
 
 
    <link href=»http://getbootstrap.com/dist/css/bootstrap.min.css» rel=»stylesheet»>
 
    <link href=»http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css» rel=»stylesheet»>
    <link href=»signup.css» rel=»stylesheet»>
 
 
</head>
 
<body>
 
    <div class=»container»>
        <div class=»header»>
            <nav>
                <ul class=»nav nav-pills pull-right»>
                    <li role=»presentation»><a href=»/»>Home</a>
                    </li>
                    <li role=»presentation» class=»active»><a href=»#»>Sign In</a>
                    </li>
                    <li role=»presentation»><a href=»/signUp»>Sign Up</a>
                    </li>
                </ul>
            </nav>
            <h3 class=»text-muted»>Python Flask App</h3>
        </div>
 
        <div class=»jumbotron»>
            <h1>Bucket List App</h1>
            <form class=»form-signin»>
                <label for=»inputEmail» class=»sr-only»>Email address</label>
                <input type=»email» name=»inputEmail» id=»inputEmail» class=»form-control» placeholder=»Email address» required autofocus>
                <label for=»inputPassword» class=»sr-only»>Password</label>
                <input type=»password» name=»inputPassword» id=»inputPassword» class=»form-control» placeholder=»Password» required>
 
                <button id=»btnSignIn» class=»btn btn-lg btn-primary btn-block» type=»submit»>Sign in</button>
            </form>
        </div>
 
 
 
        <footer class=»footer»>
            <p>&copy;
        </footer>
 
    </div>
</body>
 
</html>

В app.js добавьте обработчик запроса /SignIn который будет отображать страницу signin.html .

1
2
3
4
5
app.get(‘/signIn’, function(req, res) {
    res.sendFile(‘signin.html’, {
        ‘root’: __dirname + ‘/public/signin’
    });
});

Аналогичным образом добавьте signup.html в папку public/signup со следующим HTML-кодом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<!DOCTYPE html>
<html lang=»en»>
 
<head>
    <title>Python Flask Bucket List App</title>
 
 
    <link href=»http://getbootstrap.com/dist/css/bootstrap.min.css» rel=»stylesheet»>
 
    <link href=»http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css» rel=»stylesheet»>
    <link href=»signup.css» rel=»stylesheet»>
 
 
</head>
 
<body>
 
    <div class=»container»>
        <div class=»header»>
            <nav>
                <ul class=»nav nav-pills pull-right»>
                    <li role=»presentation»><a href=»/»>Home</a>
                    </li>
                    <li role=»presentation»><a href=»/signIn»>Sign In</a>
                    </li>
                    <li role=»presentation» class=»active»><a href=»#»>Sign Up</a>
                    </li>
                </ul>
            </nav>
            <h3 class=»text-muted»>Python Flask App</h3>
        </div>
 
        <div class=»jumbotron»>
            <h1>Bucket List App</h1>
            <form class=»form-signin» action=»/register» method=»post»>
                <label for=»inputFirstName» class=»sr-only»>First Name</label>
                <input type=»name» name=»inputFirstName» id=»inputFirstName» class=»form-control» placeholder=»First Name» required autofocus>
                <label for=»inputLastName» class=»sr-only»>Last Name</label>
                <input type=»name» name=»inputLastName» id=»inputLastName» class=»form-control» placeholder=»Last Name» required autofocus>
                <label for=»inputUsername» class=»sr-only»>Username</label>
                <input type=»name» name=»inputUsername» id=»inputUsername» class=»form-control» placeholder=»Username» required autofocus>
                <label for=»inputPassword» class=»sr-only»>Password</label>
                <input type=»password» name=»inputPassword» id=»inputPassword» class=»form-control» placeholder=»Password» required>
                <label for=»inputPhone» class=»sr-only»>Password</label>
                <input type=»number» name=»inputPhone» id=»inputPhone» class=»form-control» placeholder=»Phone» required>
 
                <button id=»btnSignUp» class=»btn btn-lg btn-primary btn-block» type=»submit»>Sign up</button>
            </form>
        </div>
 
 
 
        <footer class=»footer»>
            <p>&copy;
        </footer>
 
    </div>
</body>
 
</html>

Добавьте обработчик запроса с именем signUp в app.js

1
2
3
4
5
app.get(‘/signUp’, function(req, res) {
    res.sendFile(‘signup.html’, {
        ‘root’: __dirname + ‘/public/signup’
    });
});

Сохраните изменения и перезапустите сервер. Укажите в браузере http: // localhost: 3000, и приложение должно быть запущено. Нажмите на ссылку для входа и регистрации на странице, и соответствующие страницы должны отображаться.

Чтобы реализовать функцию регистрации, мы будем вызывать REST API Python Eve. Мы будем вызывать этот API из серверной части Node.js поскольку для этого требуется передать имя пользователя и пароль для аутентификации службы. Итак, чтобы не допустить раскрытия имени пользователя и пароля для аутентификации в скриптах, мы сделаем этот вызов из Node.js

Давайте сначала создадим обработчик запросов на register для обработки функциональности регистрации.

1
2
3
app.post(‘/register’, function(req, resp) {
   // Code will be here
});

Нам потребуется body-parser для анализа данных, отправленных из формы. Установите body-parser с помощью менеджера пакетов NPM.

1
npm install body-parser

После того, как body-parser был установлен, необходимо это сделать внутри app.js

1
bodyParser = require(‘body-parser’)

Чтобы использовать body-parser для анализа опубликованных данных формы, нам нужно использовать их в нашем приложении.

1
2
3
app.use(bodyParser.urlencoded({
    extended: true
}));

Внутри обработчика /register мы можем проанализировать данные формы, как показано:

1
2
3
4
5
var _firstName = req.body.inputFirstName;
var _lastName = req.body.inputLastName;
var _username = req.body.inputUsername;
var _password = req.body.inputPassword;
var _phone = req.body.inputPhone;

Мы будем использовать request для вызова API Eve. Итак, установите запрос в приложение.

1
npm install request

Требовать request в app.py

1
request = require(‘request’)

Создайте параметры для вызова API, как показано:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
var options = {
    url: ‘http://127.0.0.1:5000/user/’,
    method: ‘POST’,
    auth: {
        user: ‘admin’,
        password: ‘admin’
    },
    formData: {
        firstname: _firstName,
        lastname: _lastName,
        username: _username,
        password: _password,
        phone: _phone
    }
}

Мы определили детали для запроса POST в опциях. admin_username и admin_password — это имя пользователя и пароль для аутентификации, необходимые для доступа к API создания пользователя Eve.

Далее давайте воспользуемся request чтобы сделать звонок.

1
2
3
4
5
6
7
8
request(options, function(err, res, body) {
    if (err) {
        console.log(err);
        return;
    }
    console.log(‘Response: ‘, res)
    console.log(‘Returned data: ‘, body)
})

Сохраните изменения и перезапустите сервер. В браузере укажите http: // localhost: 3000 и перейдите к экрану регистрации. Введите данные и нажмите кнопку регистрации. Проверьте окно терминала на предмет ответа и сведений о создании пользователя, возвращаемых из вызова API.

Если во время регистрации возникает ошибка, мы передаем сообщение об ошибке на страницу регистрации. Мы будем использовать шаблонизатор EJS . Сначала давайте установим EJS.

1
npm install ejs

EJS установку EJS , добавьте следующую строку кода, чтобы установить папку просмотра и механизм просмотра.

1
2
3
var path = require(‘path’);
app.set(‘views’, path.join(__dirname + ‘/public/signup’));
app.set(‘view engine’, ‘ejs’);

Переименуйте signup.html в signup.ejs и добавьте span для отображения ошибки после кнопки отправки.

1
<span style=»color:red;»><%= error %>

Также измените signUp запроса регистрации.

1
2
3
app.get(‘/signUp’,function(req,res){
    res.render(‘signup’,{error:»})
});

Далее, если в ответе о регистрации возникнет какая-либо ошибка, мы передадим ее на страницу регистрации. Если процесс регистрации не возвращает ошибку, мы перенаправим пользователя на страницу входа.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
request(options, function(err, res, body) {
    if (err) {
        return resp.render(‘signup’, {
            error: err
        })
    }
    var result = JSON.parse(body)
    if (result._status == ‘ERR’) {
        if (result._error.code == ‘400’) {
            return resp.render(‘signup’, {
                error: ‘Username Already Exists!’
            })
        }
        return resp.render(‘signup’, {
            error: result._issues.username
        })
    } else {
        console.log(‘All good’);
        resp.redirect(‘/signIn’);
    }
})

Сохраните все изменения и перезапустите сервер. Укажите в браузере http: // localhost: 3000 / signUp и попробуйте зарегистрироваться, используя существующее имя пользователя. Поскольку имя пользователя уже существует, вы должны получить ошибку.

Имя пользователя уже существует ошибка при регистрации

AngularJS предоставляет сервис под названием $ http, который помогает выполнять вызовы REST API. Из документов AngularJS,

Служба $http является основной службой Angular, которая облегчает связь с удаленными HTTP-серверами через объект браузера XMLHttpRequest или через JSONP .

Скопируйте содержимое тела файла index.html и создайте новый файл с именем public/home/home.html .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<div class=»container»>
    <div class=»header»>
        <nav>
            <ul class=»nav nav-pills pull-right»>
                <li role=»presentation» class=»active»><a href=»#»>Home</a></li>
                <li role=»presentation»><a href=»#/signin»>Sign In</a></li>
                <li role=»presentation»><a href=»/signUp»>Sign Up</a></li>
            </ul>
        </nav>
        <h3 class=»text-muted»>Angular Node App</h3>
    </div>
 
    <div class=»jumbotron»>
        <h1>Angular Node App</h1>
        <p class=»lead»></p>
        <p><a class=»btn btn-lg btn-success» href=»/signUp» role=»button»>Sign up today</a></p>
    </div>
 
 
 
    <footer class=»footer»>
        <p>&copy;
    </footer>
 
</div>

В домашней папке создайте файл с именем home.js и определите home модуль и конфигурацию маршрутов, как показано:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
‘use strict’;
 
angular.module(‘home’, [‘ngRoute’])
 
.config([‘$routeProvider’, function($routeProvider) {
  $routeProvider.when(‘/home’, {
    templateUrl: ‘../home/home.html’,
    controller: ‘HomeCtrl’
  });
}])
 
.controller(‘HomeCtrl’, [function() {
 
}]);

Аналогичным образом замените HTML-код signin.html содержимым тела signin.html . Мы будем обрабатывать маршрутизацию страницы входа через приложение AngularJS.

Внутри папки signin создайте файл с именем signin.js и добавьте следующие сведения о конфигурации маршрута.

01
02
03
04
05
06
07
08
09
10
‘use strict’;
 
angular.module(‘signin’, [‘base64′,’ngRoute’,’myAppService’])
 
.config([‘$routeProvider’, function($routeProvider) {
  $routeProvider.when(‘/signin’, {
    templateUrl: ‘../signin/signin.html’,
    controller: ‘SignInCtrl’
  });
}])

В index.html мы будем использовать ngView и направлять представления приложения AngularJS. Вот как будет выглядеть index.html :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang=»en» ng-app=»myApp»>
  <head>
    <title>Angular Node App</title>
 
    
    <link href=»http://getbootstrap.com/dist/css/bootstrap.min.css» rel=»stylesheet»>
 
    <link href=»http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css» rel=»stylesheet»>
    <script src=»https://code.jquery.com/jquery-2.0.1.min.js»></script>
    <script src=»https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js»></script>
    <script src=»https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.js»></script>
    <script src=»home/home.js»></script>
    <script src=»signin/signin.js»></script>
    <script src=»index/index.js»></script>
     
  </head>
 
  <body>
 
    <div ng-view></div>
  </body>
</html>

Внутри папки index создайте файл с именем index.js который будет служить корневым файлом. В index.js мы добавим различные модули, созданные в приложении myApp . Вот файл index.js :

1
2
3
4
5
6
7
8
angular.module(‘myApp’, [
  ‘ngRoute’,
  ‘home’,
  ‘signin’
]).
config([‘$routeProvider’, function($routeProvider) {
  $routeProvider.otherwise({redirectTo: ‘/home’});
}]);

Установите angular-route с помощью bower и включите ссылку в index.html .

1
bower install angular-route
1
<script src=»../bower_components/angular-route/angular-route.js»></script>

Нам также необходимо преобразовать имя пользователя и пароль в base64 , поэтому установите angular-base64 .

1
bower install angular-base64

После установки добавьте ссылку на angular-base64 в index.html .

1
<script src=»../bower_components/angular-base64/angular-base64.js»></script>

Установите статический путь к bower_components в app.js

1
app.use(‘/bower_components’, express.static(__dirname + ‘/bower_components’));

Внутри signin.js давайте создадим контроллер с именем SignInCtrl .

01
02
03
04
05
06
07
08
09
10
11
12
13
‘use strict’;
 
angular.module(‘signin’, [‘base64′,’ngRoute’])
 
.config([‘$routeProvider’, function($routeProvider) {
  $routeProvider.when(‘/signin’, {
    templateUrl: ‘../signin/signin.html’,
    controller: ‘SignInCtrl’
  });
}])
 
.controller(‘SignInCtrl’,[‘$scope’,’$http’,’$base64′,function($scope,$http,$base64){
}]);

Мы только что создали контроллер SignInCtrl в signin.js . Мы внедрили модуль base64 в SignInCtrl .

При нажатии кнопки входа мы вызовем вышеуказанную функцию signIn для аутентификации пользователя. Итак, сначала давайте добавим директиву ngModel в поле имени пользователя и пароля на странице входа.

1
2
<input type=»text» name=»inputUsername» id=»inputUsername» ng-model=»username» class=»form-control» placeholder=»Email address» autofocus>
<input type=»password» name=»inputPassword» id=»inputPassword» ng-model=»password» class=»form-control» placeholder=»Password» >

Добавьте директиву ngClick к кнопке «Вход» в signin.html .

1
<button id=»btnSignIn» class=»btn btn-lg btn-primary btn-block» ng-click=»signIn()»>Sign in</button>

Внутри функции signIn в signIn прочитайте имя пользователя и пароль из $scope . Получив имя пользователя и пароль, мы создадим строку base64 используя angular-base64 .

1
2
3
4
5
6
7
$scope.signIn = function() {
   
    var username = $scope.username;
    var password = $scope.password;
 
    var authdata = $base64.encode(username + ‘:’ + password);
}

Перед вызовом API REST нам необходимо установить необходимые заголовки. Нам нужно установить Access-Control-Request-Headers и Access-Control-Expose-Headers .

1
2
3
4
5
6
7
$http.defaults.headers.common = {«Access-Control-Request-Headers»: «accept, origin, authorization»};
 
$http.defaults.headers.common = {«Access-Control-Expose-Headers»: «Origin, X-Requested-With, Content-Type, Accept»};
 
$http.defaults.headers.common[«Cache-Control»] = «no-cache»;
 
$http.defaults.headers.common.Pragma = «no-cache»;

Нам также нужно установить заголовок Authorization в $http . Используя base64 authData созданные с использованием username и password , установите заголовок авторизации.

1
$http.defaults.headers.common[‘Authorization’] = ‘Basic ‘+authdata;

Затем выполните вызов $http GET для API-интерфейсов REST Python Eve.

01
02
03
04
05
06
07
08
09
10
$http({
    method: ‘GET’,
    url: ‘http://127.0.0.1:5000/user/’ + username
}).
success(function(data, status, headers, config) {
    console.log(data);
}).
error(function(data, status, headers, config) {
    console.log(data, status);
});

Сохраните все изменения и перезапустите сервер. В браузере укажите http: // localhost: 3000 / signin . Попробуйте войти, используя действительное имя пользователя и пароль. Проверьте консоль браузера, и вы должны иметь пользовательские данные. Если аутентификация не удалась, вы должны иметь ошибку аутентификации.

В этом уроке мы увидели, как использовать API REST, созданные в предыдущем уроке, в наших приложениях AngularJS и Node.js Мы реализовали функции входа и регистрации в этом руководстве.

В следующей части этой серии мы будем использовать другие API для завершения нашего приложения AngularJS.

Исходный код из этого урока доступен на GitHub .