Что нам понадобится для этого урока.
- HTML и CSS
- Некоторый Javascript
- Nodejs и экспресс
- Axios
Давайте создадим папку с именем meme_generator и инициализируем проект узла, набрав npm init -y
Теперь у нас есть инициализированный проект NodeJS, давайте откроем код в этой папке и настроим нашу экспресс-конфигурацию и конфигурацию веб-серверов.
Я собираюсь создать каталог index.js, public и views.
- В общедоступном каталоге будут храниться наши статические файлы, такие как js, css, изображения и т. Д.
- В каталоге представлений будут храниться наши представления (веб-страницы).
- Index.js будет содержать код для нашего сервера.
Сначала давайте настроим наш экспресс-сервер. Давайте установим несколько модулей в эту папку, набрав npm install express ejs axios lodash
.
- Экспресс создаст наш сервер.
- ejs - это модуль шаблонов.
- axios - это библиотека HTTP-запросов, которая будет делать запросы к imgflip api.
- lodash - это некоторые функции для списка, которые нам понадобятся.
Теперь, когда мы установили наши модули, давайте откроем наш index.js и напишем код.
// IMPORTS const express = require('express'); const axios = require('axios').default; const _ = require('lodash');
// CONSTANTS const app = express();
// MIDDLEWARES app.use(express.json()); // This will parse json payload. app.use(express.urlencoded({extended: true}); // This will parse urlencoded payload. app.use(express.static('public')); // This will serve public directory on our server. app.set('view engine', 'ejs'); // So express uses ejs as its templating engine.
// Routes
// Listeing to server app.listen(3000, () => { console.log("Server is running on http://localhost:3000"); });
Теперь у нас есть готовый код и код сервера. Для его запуска нам понадобится Nodemon (библиотека, которая повторно запускает файл при изменении кода). Давайте установим это глобально. npm install -g nodemon
Теперь давайте запустим этот index.js. Введите nodemon index.js
в свой терминал.
Если открыть браузер и перейти на http://localhost:3000
. Появится сообщение.
cannot get '/'
Это означает, что наш сервер работает правильно. Теперь давайте настроим несколько маршрутов.
Здесь я создам два маршрута.
- ’/’ Будет содержать наш генератор мемов.
- «/ Generate» будет иметь метод POST и отправлять запрос в imgflip API и возвращать ответ.
// IMPORTS
const express = require('express');
const axios = require('axios').default;
const _ = require('lodash');
// CONSTANTS
const app = express();
// MIDDLEWARES
app.use(express.json()); // This will parse json payload.
app.use(express.urlencoded({extended: true}); // This will parse urlencoded payload.
app.use(express.static('public')); // This will serve public directory on our server.
app.set('view engine', 'ejs'); // So express uses ejs as its templating engine.
// Routes
app.get('/', (req, res) => {
return res.render("index");
});
app.post("/generate", (req, res) => {
return res.send("Hello World!");
});
// Listeing to server
app.listen(3000, () => {
console.log("Server is running on http://localhost:3000");
});
Теперь наш код настроен, давайте перейдем к нашему интерфейсу. Создайте файл с именем index.ejs
в вашем views
каталоге.
Напишите код для отправки почтового запроса на /generate
маршрут с параметрами template_id, username, password, text0, text1
с типом кодирования form-urlencoded. Как в блоке кода ниже.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Input</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="d-flex">
</div>
<form action="/generate" method="POST" enctype="application/x-www-form-urlencoded">
<div class="input-container">
<label for="">ID</label>
<input id="template_id" required name="template_id" type="text">
</div>
<div class="input-container">
<label for="">Username</label>
<input required name="username" type="text">
</div>
<div class="input-container">
<label for="">Password</label>
<input required name="password" type="password">
</div>
<div class="input-container">
<label for="">Upper text</label>
<input required name="text0" type="text">
</div>
<div class="input-container">
<label for="">Lower Text</label>
<input required name="text1" type="text">
</div>
<button type="submit" class="btn-primary">
Send
</button>
</form>
</div>
</body>
</html>
Давайте теперь оформим это в стиле: Создайте style.css
в своем общедоступном каталоге.
.container{
display: flex;
flex-direction: column;
}
.input-container{
margin: 15px;
display: flex;
flex-direction: column;
width: 30%;
}
.input-container label{
font-size: 24px;
font-family: 'Consolas', sans-serif;
font-weight: bold;
}
.input-container input{
border-radius: 25px;
padding: 10px;
border: 1px solid grey;
}
.btn-primary{
width: 30%;
height: 50px;
border: 1px solid white;
border-radius: 15px;
margin: 15px;
background-color: rgb(4, 156, 194);
color: white;
cursor: pointer;
}
.d-flex{
display: flex;
}
.d-flex img{
width: auto;
height: 100px;
margin: 10px;
border: 1px solid black;
cursor: pointer;
}
Если вы перейдете к маршруту /
в своем браузере, вы увидите это.
Теперь давайте настроим наш POST-маршрут. В index.js
файле. Сделайте запрос к imgflip api и передайте параметры, которые мы получили при отправке запроса с нашей индексной страницы нашего сервера.
app.post("/generate", (req, res) => {
axios
.post(
"https://api.imgflip.com/caption_image",
{},
{
params: {
template_id: req.body.template_id,
username: req.body.username,
password: req.body.password,
text0: req.body.text0,
text1: req.body.text1,
},
}
)
.then((response) => {
return res.send(`<img src=${response.data.data.url}>`);
}).catch((e) => {
return res.status(403).send("403 Client Error")
});
});
ПРИМЕЧАНИЕ. Вам понадобятся имя пользователя и пароль для отправки запроса на imgflip api. Создайте учетную запись на imgflip.
Теперь, когда у нас есть полностью завершенный маршрут POST, давайте создадим интерфейс.
Давайте возьмем все шаблоны мемов из imgflip api и отобразим 10 случайных шаблонов meme_template, которые наш пользователь может выбрать. Перейдите на свой /
маршрут и напишите этот код.
app.get("/", (req, res) => {
axios
.get("https://api.imgflip.com/get_memes")
.then((memes) => {
return res.render("index", {
memes: _.sampleSize(memes.data.data.memes, 10)
});
})
.catch((e) => {
return res.status(500).send("500 Internal Server Error");
});
});
- Метод sampleSize принимает список в качестве аргумента и количество размеров и выдает количество случайных мемов.
- если есть ошибка, будет сгенерировано сообщение об ошибке интернет-сервера.
Теперь давайте переберем и отобразим изображение в нашем index
представлении.
<div class="container">
<div class="d-flex">
<% for(const i of memes){ %>
<img class="meme_image" id=<%= i.id %> src=<%= i.url %>>
<% } %>
</div>
<form action="/generate" method="POST" enctype="application/x-www-form-urlencoded">
...
</div>
Теперь мы хотим добавить прослушиватель событий ко всему изображению, чтобы, когда мы нажимаем на изображение, его идентификатор менялся при щелчке.
... </body>
<script> var images = document.getElementsByClassName("meme_image"); var templateInput = document.getElementById("template_id"); for(const i of images){ i.addEventListener('click', (e) => { templateInput.value = i.id; }); } </script> </html>
Теперь наш проект готов. Если вы нажмете на изображение и введете свое имя пользователя, пароль и текст и нажмете «Отправить», ваш мем будет сгенерирован.
Вы можете скачать этот исходный код с моего Github.
Посетите этот проект на Github
Также посетите мой блог Вот ссылка