Ошибка при обновлении одной и той же страницы дважды - PullRequest
1 голос
/ 11 апреля 2020

Я пытаюсь развернуть приложение angular на удаленном сервере, используя nodejs и nginx. Я построил приложение и обслуживаю его с помощью приложения узла. Nginx действует здесь как обратный прокси. Я могу зайти на сайт и перемещаться без проблем. Однако, когда я пытаюсь обновить sh текущую страницу, мой браузер больше не может ее найти: в ответ появляется 404.

Но если я вхожу в домен в строке URL-адреса, я снова могу получить доступ к веб-сайт.

Кто-нибудь знает, где я допустил ошибку?

Вот код и конфигурация для приложения узла и для nginx:

var express  = require('express');
var app      = express();                               // create our app w/ express
var morgan = require('morgan');             // log requests to the console (express4)
var bodyParser = require('body-parser');    // pull information from HTML POST (express4)
var methodOverride = require('method-override'); // simulate DELETE and PUT (express4)
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const mustacheExpress = require("mustache-express");

dotenv.config();

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

mongoose.connect(process.env.DB_CONNECT, { useNewUrlParser: true }, () => {
    console.log("connected to DB !");
  });

app.use(express.static("../front-end/dist/website"));                 
app.use(morgan('dev'));                                         // log every request to the console
app.use(bodyParser.urlencoded({'extended':'true'}));            // parse application/x-www-form-urlencoded
app.use(bodyParser.json());                                     // parse application/json
app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
app.use(methodOverride());

// Middleware
app.use(express.json());

// Templating
app.engine("html", mustacheExpress());

//import routes
const authRoute = require("./routes/auth");
const devisRoute = require("./routes/devis");
const messageRoute = require("./routes/message");
const actuRoute = require("./routes/actu");

//Routes middlewares
app.use("/api/user", authRoute);

app.use("/api/sendDevis", devisRoute);

app.use("/api/message", messageRoute);

app.use("/api/actu", actuRoute);


// listen (start app with node server.js) ======================================
app.listen(3000);


server {

        root /var/www/domain.com/html;
        index index.html index.htm index.nginx-debian.html;

        server_name domain.com www.domain.com;

        location / {
              proxy_pass http://localhost:3000;
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection 'upgrade';
              proxy_set_header Host $host;
              proxy_cache_bypass $http_upgrade;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem; # m                                                         anaged by Certbot
    ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem; #                                                          managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


}
server {
    if ($host = www.domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = domain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80;
        listen [::]:80;

        server_name domain.com www.domain.com;
    return 404; # managed by Certbot

}

1 Ответ

1 голос
/ 12 апреля 2020

Это простая ловушка, в которую можно попасть при выполнении маршрутизации на стороне клиента с помощью одностраничного приложения.

Хитрость в том, что при навигации в браузере браузер не отправка запросов на ваш сервер. При обновлении sh страницы браузер отправляет запрос на сервер . Поскольку вы создаете SPA, вся информация о том, что находится на этой странице, содержится в вашем Javascript, а этот Javascript загружен в ваш файл index.html. Единственный файл, который существует на вашем сервере, это ваш root файл, а промежуточное ПО express.static отображает URL-адреса на ваши файлы, поэтому для него нет файла для поиска (отсюда 404).

Что вы необходимо на стороне сервера всегда обслуживать файл index.html независимо от того, какой файл html запрашивается .

Самое простое решение - добавить обработчик возврата last в вашей маршрутизации с использованием встроенной функции Express .sendFile(). Простой, без нюансов способ будет выглядеть примерно так:

// ... ^^ all your other routes
router.get("*",
  // The '*' means match *everything*
  (req,res)=>{
    res.sendFile('index.html'); // Probaby need to set some options here to start in the right directory...
  }
);

Возможно, вы захотите использовать другое промежуточное ПО или добавить свои собственные функции для включения сжатия, et c, но идея будет то же самое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...