Страницы

Поиск по вопросам

Показаны сообщения с ярлыком express. Показать все сообщения
Показаны сообщения с ярлыком express. Показать все сообщения

пятница, 24 января 2020 г.

Express + Node. js partial

#nodejs #express

проблема не выводит виджет (partial)  в шаблон houme

houme

Добро пожаловать на сайт турфирмы

{{>weather}} server function getWeatherData(){ return { locations: [{ name:'Protland', forecatUrl: 'http://www.wunderground.com/US/OR/Portland.html', iconUrl: 'http://..icons-ak.wxug.com/i/c/k/cloudy.gif', weather:'Cloudy', temp: '54.1 F (12.3 C)' }, { name: 'Band', forecatUrl: 'http://www.wunderground.com/US/OR/Band.html', iconUrl: 'http://..icons-ak.wxug.com/i/c/k/rain.gif', weather:'Rain', temp: '55.0 F (12.8 C)' }, { name: 'Minsanita', forecatUrl: 'http://www.wunderground.com/US/OR/Minzanita.html', iconUrl: 'http://..icons-ak.wxug.com/i/c/k/rain.gif', weather:'Rain', temp: '55.0 F (12.8 C)' }] }; } //Виджет app.use(function(req, res, next){ if (!res.locals.partials) res.locals.partials = {}; res.locals.partials.weatherContext = getWeatherData(); next(); }); views/partial/weather
{{#each partials.weatherContext.locations}} {{/each}} Источник: Weather Ground
**Это пример с учебника. Почему не работает не пойму. Шаблон с ссылкой выводит нормально все что находиться в блоке each вообще не выводит.


Ответы

Ответ 1



Уххх, как весело:) Вы используете шаблонный менеджер handlebars. Обычный пакет handlebars у Вас уже 99% стоит, но сверху еще надо сделать вот так npm i hbs Добавляем в какую-нибудь корневую для рэндэров middleware следующий код const hbs = require('hbs'); // лучше вне middleware // папка с partials!! hbs.registerPartial('weather', fs.readFileSync(__dirname + '/../views/partials/weather.hbs', 'utf8')); Обратите внимание на строку с путем - начинается со слеша, задается относительно файла, в котором находится. После указанных выше манипуляций у меня Ваш пример, хоть чуть и упрощенный стартанул. Если Вам не удастся воспроизвести по этому ответу, выложу код на гит, или дополню ответ где надо.

Ответ 2



Попробуйте так: app.use(function(req, res, next){ if (!res.locals.partials) res.locals.partials = {}; res.locals.partials.weatherContext = getWeatherData(); next(); }); Поставьте перед началом маршрутизации: app.get('/', function (req, res) { res.render('home'); });

пятница, 3 января 2020 г.

NodeJS - настройка live reload

#javascript #nodejs #express

Вопрос - как настроить сервер на NodeJS, чтобы при изменении моделей, контроллеров
и других файлов приложение, изменения сразу вступали в силу, а не приходилось выключать
dev-сервер с помощью Ctrl+C и заново его запускать?
    


Ответы

Ответ 1



1) Один из таких скриптов supervisor. npm install -g supervisor. После установки сервер запускаете через него: supervisor app.js. Единственный нюанс - он не увидит вновь созданные файлы. Поэтому если в рабочей папке будет создан новый файл, сервер надо перезапустить 2) Вот нашел еще одну утилиту https://www.npmjs.com/package/pm2. Более мощная штука, чем supervisor. После запуска pm2 start nameFile.js создает демона - и консоль, из которой происходил запуск можно закрыть (открепляет работу сервера от консоли). Так же, pm2 может самостоятельно создать файлы необходимой конфигурации для добавления в автозапуск сервера NodeJs (после перезагрузки ОС). Это очень нужная вещь, при работе сервера NodeJs на VPS. Для этого необходимо, после запуска сервера NodeJs, написать команду pm2 startup, а потом pm2 save.

Ответ 2



sudo npm install -g nodemon после запускаешь с помощю команды nodemon <имяФайла>

пятница, 27 декабря 2019 г.

Первый опыт в node.js Можно ли не переделывая с нуля получить сносный результат?

#nodejs #mongodb #инспекция_кода #express #mongoose

Мой первый опыт программирования, если не считать студенческих лабораторных на Delphi(и
те были очень давно). 

Цель: "приложение" которое на первой странице выдает кликабельный список из имен
юзеров(имена берем в mongodb), а при клике на юзера перебрасывает на другую страницу,
где уже отображает(беря из базы) подробные сведения о выбранном юзере.
Основательно переписал, получил вот это. 

Вопросы:


Общая структура более-менее адекватна? Дорабатывать имеющееся или же переделывать
с нуля? 
В модуле userModel я подключаюсь к базе данных. Там предусмотрена простейшая обработка
ошибки в виде сообщения в консоль. Как бы мне сделать так, чтобы эта ошибка попадала
в express и я мог вывести в браузере объект ошибки? 




//app.js:

var express = require('express');
var app = express();

var router = require('./router/router');
app.use(router);
app.listen(3000, function() {
  console.log('Listening on port 3000!\nDatabase on mlab.com');
});

//router.js:
var express = require('express');
GetFirstPage = require('../lib/GetPages').firstPage;
GetSecondPage = require('../lib/GetPages').secondPage;

var router = express.Router();
router.get('/', GetFirstPage);
router.get('/user?:id', GetSecondPage);
router.use(express.static('public'));
module.exports = router;
//userModel:
const mongoose = require('mongoose');
mongoose.connect(require('../credentials').mongo, function(err) {
  if (err) console.log('Error database connection\n', err)
});


const userShema = mongoose.Schema({
  name: String,
  age: String,
  disciplines: String,
});

module.exports = mongoose.model('User', userShema);

//GetPages.js:
var express = require('express');
var app = express();
var _ = require('underscore');
const User = require('./exportFromDB').user;
const NamesList = require('./exportFromDB').namesList;

module.exports.firstPage = function(req, res) {
  Promise.all([
    NamesList(), readMainPage()
  ]).then(function(results) {
    const list = results[0].map(function(item) {
      return item.name
    })
    res.send(results[1]({
      'list': list
    }))
  })
}

module.exports.secondPage = function(req, res) {
  Promise.all([
    User(decodeURIComponent(req.query.id)), readSecondPage()
  ]).then(function(results) {
    res.send(results[1]({
      name: results[0][0].name,
      age: results[0][0].age,
      disciplines: results[0][0].disciplines
    }))
  })
}

function readMainPage() {
  const myFile = require('../lib/exportFile').mainPage;
  return myFile();
}

function templateMainPage(template) {
  res.send(template({
    'list': List
  }))
}

function readSecondPage() {
  const myFile = require('../lib/exportFile').secondPage;
  return myFile();
}
//ExportDB.js
userModel = require('./userModel');


module.exports.namesList = () => {
  return new Promise(function(resolved, rejected) {
    userModel.find({}, 'name -_id', function(err, data) {
      resolved(data)
    })
  })
}
module.exports.user = (url) => {
  return new Promise(function(resolved, rejected) {
    userModel.find({
      name: url
    }, function(err, data) {
      resolved(data)
    })
  })
}



    


Ответы

Ответ 1



Как-то так стандартно выглядит запрос страницы всех юзеров: app.get('/', function(req, res) { users.find({}, (err, docs) => { res.locals.users = docs; res.render('list'); }; }; А в шаблоне страницы списка - юзеры выводятся в цикле each user in users, где каждый обёртывается в ссылку с атрибутом такого вида href="/users/#{user._id}" (или какой-там у вас синтаксис шаблонизатора) А запрос страниц отдельных юзеров - app.get('/users/:id', ..., и в его обработчике, в объекте запроса значением параметра req.params.id будет айдишник юзера в базе, по которому он легко и запрашивается - app.get('/users/:id', function(req, res) { users.find({_id: req.params.id}, (err, result) => { res.locals.user = result; res.render('user'); }; }; Шаблон страницы получил объект юзера - user._id user.name user.age и т.д. Всего и делов - спасибо ТиДжею Каравайчуку (или как там его) за Express.

пятница, 20 декабря 2019 г.

Next() в Express

#nodejs #express

После очередного перечитывания документации Express. В мою голову так и не пришло
понимание функции next(). Прошу вас объяснить мне. Для чего и в каких случаях нужно
использовать next(), что эта функция возвращает? Давайте разберем на простом примере

app.get('/users/:id?', function(req, res, next) {
     var id = req.params.id;
     if (id) {
        // делаем что-то
    } else {
        next();
    }
});


Что делает в данном случае next()
    


Ответы

Ответ 1



Фреймворк Express.js построен на концепции ПО промежуточного уровня (англ. middleware). Суть этого подхода в том, что запрос к каждому ресурсу обрабатывается не одним единственным действием контролера (специально опускаю возможные препроцессоры и прочее), а целым стеком функций. При этом, каждая из этих функций может каким-то образом изменять запрос/ответ и передавать управление следующей функции. Так же, какая-то из функций может сгенерировать конечный ответ и отдать его пользователю, прекращая, тем самым, движение вниз по стеку ПО промежуточного уровня. Связывание элементов ПО промежуточного уровня в Express как раз и осуществляется с помощью функции next. Эта функция может быть использована для двух целей: Передать управление следующей функции в стеке (для этого ф-ция next вызывается без параметров). Сообщить фреймворку об ошибке и передать управление специализированному ПО промежуточного уровня (для этого функции next передается объект ошибки). Если же функция next не вызывается, то это значит, что движение вниз по стеку функций должно быть закончено. Проиллюстрирую все вышесказанное на примере. Типичное приложение на node.js с использованием Express выглядит следующим образом: var app = require('express')(); // Здесь мы будет добавлять к каждому входящему запросу время, // когда он поступил с точностью до миллисекунд. В реальном // приложении здесь может быть код инициализации сессии, // аутентификации, авторизации или чего-то еще. app.use('/', function(req, res, next) { req.initTimestamp = (new Date()).getTime(); // Обратите внимание, функция "next" вызывается БЕЗ ПАРАМЕТРОВ. // Это позволяет предать управление следующему обработчику. next(); }); // Этот обработчик проверяет время, инициализации запроса и, // если количество миллисекунд четное, то он завершается с ошибкой. // В реальных приложениях, это может быть, например, ошибка // соединения с базой данных. app.use('/', function(req, res, next) { if (req.initTimestamp % 2 === 0) { // Обратите внимание, функции "next" передается ОБЪЕКТ ОШИБКИ. // Он будет использован чуть позже. next(new Error('Not today. Sorry.')); } else { // Просто отдаем ответ клиенту. Вызов "next" здесь НЕ НУЖЕН, // все следующие обработчики будут проигнорированы. res.send('The sun is shining. Have a nice day :)'); } }); // А вот здесь мы обрабатываем все те ошибки, что были переданы // как аргументы в функцию "next". Обратите внимание, у обработчика // ЧЕТЫРЕ аргумента. "err" - это тот самый объект ошибки из // предыдущего обработчика. app.use('/', function(err, req, res, next) { // Просто отправляем сообщение об ошибке клиенту. res.send(err.message); // А вместо этого мы вполне могли бы передать управление // СЛЕДУЮЩЕМУ обработчику ошибок, вот так // next(err); });

четверг, 19 декабря 2019 г.

Ошибка при авторизации в VK через приложение на node.js

#nodejs #vkontakte_api #express

Добрый день, товарищи!

Возникла проблема - не могу справиться с авторизацией через ВК в своем приложении
(node.js + express.js + passport.js). При попытке авторизации браузер показывает следующее
сообщение:


  {"error":"invalid_request","error_description":"redirect_uri is
  incorrect, check application domain in the settings page"}


Все делал по примеру c данной страницы: Passport-VKontakte
    


Ответы

Ответ 1



Убедитесь, что у вас адрес домена в redirect_url и базовый домен в приложении (в вконтакте) совпадают.

Ответ 2



Если кто-то в будущем столкнется с этой проблемой, возможно вам поможет следующее: Убедитесь, что тип созданного вами приложения во Вконтакте поддерживает стороннюю авторизацию: standalone или веб-сайт Для standalone приложений убедитесь, что в настройках приложения взведена галочка open API. Пусть вас не смущает, что open API не имеет ничего общего с Oauth2. Если вы размещаете приложение на кириллическом домене, в настройках должен быть указан домен приложения именно в кириллическом наборе, а не в punycode. Да, фактически вариант punycode должен быть тождественным кириллице, но во Вконтакте вот так вот сложилось.

Ответ 3



Мне не удалось решить проблему вот так: Нужно в настройках приложения Вконтакте сделать пустым поле Доверенный redirect URI:. После этого у меня все заработало.

Ответ 4



При использовании API в мобильном приложении заработало после того как стал передавать пустой redirect_uri. Пример запроса: https://oauth.vk.com/authorize?client_id=123456&redirect_uri=&response_type=token&scope=0&v=5.92

понедельник, 15 июля 2019 г.

Сохранение логина/пароля в браузере после редиректа в expressjs?

Подскажите, как активировать окно сохранения логина/пароля в браузере, если после этого самого логина у меня происходит редирект.
P.S> Если заменить редирект на res.send, то всё работает, но как тогда вернуть пользователя на предыдущую страницу?
app.put('/login', function(req, res, next) { pool.query('SELECT idperson, nickname, email, password FROM person WHERE email=? AND password=?', [req.body.email, req.body.password], function(err, rows, fields, next) { if (err) return next(err); if (!rows[0]) console.log('Неверные данные'); else { req.session.idperson = rows[0].idperson; req.session.nickname = rows[0].nickname; } res.redirect('back'); }); });
HTML с шаблонизатором(pug)
form(method="post" action="/login" enctype="application/x-www-form-urlencoded") input(type="email" placeholder="введите email" name="email" required) input(type="password" placeholder="введите пароль" name="password" pattern="[A-Za-z0-9]{6,30}" title="Пароль может содержать только латинские буквы(a-z) и цифры(0-9), от 6 до 30 символов." required) input(type="hidden" name="_method" value="PUT") input(type="submit" name="login" value="Войти")


Ответ

Сохранение пароля, как ни странно, происходит только в случае res.send :(
Итого, рабочий код:
form(id="test" method="post" action="/login") input(type="email" required) input(type="password" required) input(type="submit" value="субмит")
app.post('/login', function(req, res, next) { var backurl="Возвращаемся назад "; res.send(backurl); });

понедельник, 8 июля 2019 г.

Передача дополнительных переменных в роутер

Доброго!
Не совсем ещё втянулся в прелести Node.JS, потому туплю..
В принципе, тривиальный сервер app.js
router = require('./routes'); // Каталог с роутерами var isDebug = true; // Переменная для примера (которую и хочется передать) var port = 666; var app = express(); app.listen(port, function(){ console.log('SERVER STARTED AT PORT: ' + port); }); router(app, connection, isDebug); // Передали переменую
Далее, в ./routes/index.js
var users = require('./users'); // Куда будем отсылать module.exports = function (app, isDebug) { app.get('/users', users.login); // <-- Вот как именно сюда передать isDebug??? };
Очередным параметром - не хочет, ругается:
Error: Route.get() requires callback functions but got a [object Boolean]
А если далать сразу ./routes/index.js, к примеру, так:
module.exports = function (app, connection, isDebug) { app.get('/users', function (req, res) { if (isDebug) console.log('Trying auth...'); }); };
Всё работает, но так накопится очень много кода в ./routes/index.js, который хотелось бы разделить.. Для примера, ./routes/user.js
var login = function (req, res) { if (isDebug) console.log('Trying auth...'); }; module.exports.login = login;
Всё, естесственно, упрощено. Как бы это поизящнее оформить, посоветуйте, пожалуйста, коллеги?


Ответ

Один из простых вариантов добавления неких дополнительных параметров в обработку запроса - middleware. Например в корневом роутере:
router.use(function (req, res, next) { req.yourVar = "something"; req.isDebug = true; next(); });
или на уровне приложения
app.use(function (req, res, next) { req.yourVar = "something"; req.isDebug = true; next(); });
Дополнительную информацию можно найти здесь

вторник, 25 июня 2019 г.

express.js не могу получить post данные из формы

Есть следующая форма:


и файл server.js:
var express = require("express");
var bodyParser = require('body-parser'); var multer = require('multer'); // v1.0.5 var upload = multer(); // for parsing multipart/form-data
var app = express();
app.use(bodyParser.json()); // for parsing application/json app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.set("view engine","ejs");
app.use(express.static(__dirname + "/public"));
app.get("/", function(req,res){ res.render("pages/index", { title: "Главная", msg: "Привет Мир!", data: q, info: "" }); });
app.post('/', upload.array(), function (req, res, next) { console.log(req.body); //{} console.log(req.body.title); //undefined console.log(req.body.data); //undefined
res.json(req.body); //{} });
app.get("/hello", function(req,res){ res.render("pages/other", { title: "Другая страница", msg: "hello world" }); });
app.use(function(req, res, next) { res.status(404).render("pages/error", { title: "ошибка 404", msg: "ошибка 404" });
res.status(500).render("pages/error", { title: "ошибка 500", msg: "ошибка 500" }); });
app.listen(8080); console.log("Сервер запущен!");
Делаю по туториалам, недавно начал с этим разбираться, столкнулся с тем, что создал форму, но получить на сервере данные никак я не могу. пробовал и req.query, и req.params('title') -- undefined.
Пакеты установил которые подключаю.
Собственно... много информации на английском языке -- может я что то упускаю?
Вопрос: Как получить данные из формы передаваемые методом post и обработать их на сервере используя технологии nodejs и express.js?


Ответ

Для отправки данных формы необходимо проименовать поля.


В name - с каким названием параметр прилетит серверу. id - ид инпута для браузера, с сервером не связан никак.