#node.js #api #express #nginx #post
#node.js #API #экспресс #nginx #Публикация
Вопрос:
Я следовал этому руководству, чтобы развернуть мое приложение node express на digital ocean droplet с использованием обратного прокси-сервера nginx: https://lengstorf.com/code/deploy-nodejs-ssl-digitalocean /
Приложение обслуживает статические веб-страницы и имеет только один post-запрос в API. Он отлично работает при локальном запуске, но когда код выполняется на сервере, отправляющем мою базовую форму, возвращается 404.
Я очень новичок в этом, это первый веб-сайт, который я пытался разместить. Я не смог найти в Интернете ничего, что помогло бы решить эту конкретную проблему, поэтому дайте мне знать, если я могу предоставить более подробную информацию. Любая помощь приветствуется.
Вот мой серверный код:
//App.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const router = require('./routes/index');
const app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', router);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
//res.render('error');
res.json({
message: err.message,
error: err
});
console.error(err.message);
});
module.exports = app;
…
//index.js
const emailListApi = require('./EmailList');
const usersApi = require('./users');
const express = require('express');
const router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('./../public/index.html', { title: 'mySite' });
});
router.use('/api/emailList', emailListApi);
router.use('/api/user', usersApi);
module.exports = router;
…
//EmailList.js
const options = require ('./options');
const express = require('express');
const router = express.Router();
const fs = require( 'fs' );
router.post('/add', (req, res, next) => {
const name = req.body.name;
const email = req.body.email;
if(!name || !email) {
res.sendStatus(400);
console.info(' Bad request - Request does not contain name or email');
} else {
const path = req.body.filePath ?
options.assetsDir req.body.filePath : options.emailList;
if(!fs.existsSync(path)) {
fs.writeFileSync(path);
}
const entry = 'n' name ' (' email ')';
fs.appendFileSync(path, entry);
console.info(' Added ' name ' (' email ') ' ' to the distribution list');
res.sendStatus(204);
}
});
module.exports = router;
Here is the html for my form:
<!--contact.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<div>
<main>
<form name="subForm" id="subscriptionForm" method="POST" action="/api/emailList/add" autocomplete="off">
<div>
<h2>Subscribe for updates:</h2>
</div>
<div>
<div>
<label for="email">Email Address:</label>
<input name="txtEmail" id="email" type="email">
<span>Please enter a valid email address.</span>
</div>
<div>
<label for="name">Name:</label>
<input name="txtName" id="name" type="text">
</div>
</div>
<div>
<button type="submit" name="subButt">Submit</button>
</div>
</form>
</main>
</div>
<script>
const form = document.getElementById("subscriptionForm");
if (form.addEventListener) { // addEventListener for chrome
form.addEventListener("submit", function (event) {
event.preventDefault();
const xh = new XMLHttpRequest();
xh.onreadystatechange = function () {
if (xh.readyState == 4 amp;amp; xh.status == 200) {
console.log("bitchin");
}
};
xh.open("POST", "/api/emailList/add", true);
xh.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xh.send(JSON.stringify({
email: form.email.value,
name: form.name.value
}));
});
} else if (form.attachEvent) { // attachEvent for IE
form.attachEvent('onsubmit', function (event) {
event.preventDefault();
const xh = new XMLHttpRequest();
xh.onreadystatechange = function () {
if (xh.readyState == 4 amp;amp; xh.status == 200) {
console.log("bitchin");
}
};
xh.open("POST", "/api/emailList/add", true);
xh.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xh.send(JSON.stringify({
email: form.email.value,
name: form.name.value
}));
});
}
</script>
</body>
</html>
и вот мой файл конфигурации с поддержкой сайтов для nginx:
# HTTP -- redirect all traffic to HTTPS
server{
listen 80;
listen [::]:80 default_server ipv6only=on;
return 301 https://$host$request_uri;
}
server {
#Enable HTTP/2
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name alphamated.com;
# Use the Let's Encrypt certificates
ssl_certificate /etc/letsencrypt/live/mySite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mySite.com/privkey.pem;
#Include the SSL configuration from cipherli.st
include snippets/ssl-params.conf;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
proxy_ssl_session_reuse on;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
location /api {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
proxy_ssl_session_reuse on;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
}
}
Комментарии:
1. Привет, Аррон. Добро пожаловать в Stackoverflow. Вы вызываете свое приложение на порт 80 или 443. Я вижу очень разные конфигурации для двух портов в вашей конфигурации nginx.
2. Привет, Эстебан, спасибо за ответ. Весь мой трафик должен направляться через https с использованием 443. Я следовал некоторым шаблонам и руководствам для своей конфигурации, возможно, не полностью понимая их (ошибка новичка, лол), но я понимаю, что эти первые несколько строк должны перенаправлять любые http-запросы на https. Если я попытаюсь перейти на домашнюю страницу http: // alphamated.com он перенаправляет на https:// alphamated.com , и мой запрос post отображается как https:// alphamated.com/api/emailList/add , но возвращает 404