React-роутер і nginx


107

Я переходжу свою програму реагування з webpack-dev-сервера на nginx.

Коли я переходжу до кореневої URL-адреси "localhost: 8080 / login", я просто отримую 404 і в своєму журналі nginx я бачу, що він намагається отримати:

my-nginx-container | 2017/05/12 21:07:01 [error] 6#6: *11 open() "/wwwroot/login" failed (2: No such file or directory), client: 172.20.0.1, server: , request: "GET /login HTTP/1.1", host: "localhost:8080"
my-nginx-container | 172.20.0.1 - - [12/May/2017:21:07:01 +0000] "GET /login HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0) Gecko/20100101 Firefox/53.0" "-"

Де слід шукати виправлення?

Мій біт маршрутизатора в реакції виглядає так:

render(

  <Provider store={store}>
    <MuiThemeProvider>
      <BrowserRouter history={history}>
        <div>
          Hello there p
          <Route path="/login" component={Login} />
          <App>

            <Route path="/albums" component={Albums}/>

            <Photos>
              <Route path="/photos" component={SearchPhotos}/>
            </Photos>
            <div></div>
            <Catalogs>
              <Route path="/catalogs/list" component={CatalogList}/>
              <Route path="/catalogs/new" component={NewCatalog}/>
              <Route path="/catalogs/:id/photos/" component={CatalogPhotos}/>
              <Route path="/catalogs/:id/photos/:photoId/card" component={PhotoCard}/>
            </Catalogs>
          </App>
        </div>
      </BrowserRouter>
    </MuiThemeProvider>
  </Provider>, app);

І мій файл nginx ось такий:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen 8080;
        root /wwwroot;

        location / {
            root /wwwroot;
            index index.html;

            try_files $uri $uri/ /wwwroot/index.html;
        }


    }
}

Редагувати:

Я знаю, що більшість налаштувань працює, тому що коли я переходжу до localhost: 8080, не входячи в систему, я отримую і сторінку входу. це не через переспрямування на localhost: 8080 / login - це якийсь код реагування.


1
Параметри, які try_filesмають бути URI, а не імена шляхів. Спробуйте:try_files $uri $uri/ /index.html;
Річард Сміт

@RichardSmith Гаразд ... Я бачив це як ім'я до файлу index.html. Я спробував змінити це на те, що ви запропонували, але отримав той же результат. ## / wwwroot / login "не вдалося (2: Немає такого файлу чи каталогу) ## у вас є інші пропозиції. Я занурюсь у нього tonite ...
март

@martin вам це вдалося вирішити ще? Ми бачимо те саме, але там вже був рядок try_files.
Біллі Фергюсон

Відповіді:


240

Блок розташування у вашому конфігурації nginx повинен бути:

location / {
  try_files $uri /index.html;
}

Проблема полягає в тому, що запити до файлу index.html працюють, але ви наразі не повідомляєте nginx пересилати інші запити до файлу index.html.


8
Перевірте це для більш розширеної конфігурації (кешування, 404 для відсутніх .js, .css файлів тощо) gkedge.gitbooks.io/react-router-in-the-real/content/nginx.html
Gianfranco P.

Схоже, маршрутизатор React взагалі не повинен спричиняти зворотну поїздку до сервера ... чи це може бути пригнічено локально?
Скотті Х

якщо nginx не спрямовує запит до файлу index.html, то JS всередині React Router ніколи навіть не буде відомий про запит. Ця відповідь спрямовує всі запити на React, дозволяючи React Router обробляти всі запити.
Тобі

Також важливо використовувати налаштування домашньої сторінки за замовчуванням у package.json, який використовує корінь сервера. Я встановив це на ".", (Використовуйте відносні шляхи), але потім nginx намагався обслуговувати /custompath/static/main.js, що, очевидно, не вдасться, надавши непрацюючий сайт.
boerre

просто головою вгору, переконайтеся, що конфігурація фактично завантажується, моє конфліктує із замовчуванням і просто пропускається. зітхання
4c74356b41

18

Ось мої рішення

проста спроба:

location / {
    root /var/www/mysite;
    try_files $uri /index.html;
}

не більше спроб для не-html типів:

location / {
    root /var/www/mysite;
    set $fallback_file /index.html;
    if ($http_accept !~ text/html) {
        set $fallback_file /null;
    }
    try_files $uri $fallback_file;
}

не більше спроб для не-html типів та каталогу (робить try_filesсумісним із indexта / або autoindex):

location / {
    root /var/www/mysite;
    index index.html;
    autoindex on;
    set $fallback_file /index.html;
    if ($http_accept !~ text/html) {
        set $fallback_file /null;
    }
    if ($uri ~ /$) {
        set $fallback_file /null;
    }
    try_files $uri $fallback_file;
}

9

Можливо, тут справа не в тому, але для тих, хто працює з dockerконтейнером для свого reactпроекту, react-routerі webpack-dev-serverв моєму випадку у мене було все, що потрібно nginx.conf:

server {
    listen 80;
    location / {
      root   /usr/share/nginx/html;
      index  index.html index.htm;
      try_files $uri $uri/ /index.html;
    } 
    error_page 404 /index.html;
    location = / {
      root /usr/share/nginx/html;
      internal;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   /usr/share/nginx/html;
    }
  }

Але все ж nginx не надсилатиме 404 помилки в корінь /. Заглянувши в контейнер, я помітив, що є деякі конфігурації, в /etc/nginx/conf.d/default.confяких якимось чином переосмислить мої налаштування, тому видалення цього файлу в моєму dockerfileвирішило проблему:

...
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf  # <= This line solved my issue
COPY nginx.conf /etc/nginx/conf.d
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

1
Ти врятував мій день!
Білал Хуссейн


0

Для мене нічого не працювало, поки я не додав кореневу директиву. Це працювало і для мене, використовуючи зворотний проксі-сервер для встановлення кінцевої точки / api / webserver.

location / {
    root   /usr/share/nginx/html;
    try_files $uri /index.html;
}

0

Я мав справу з тією ж проблемою, і я думав, що це помилка конфіденційності, але ні. Я копіював конф-файл у /etc/nginx/conf.d/папку. Це працює у програмі dev, але у версії збірки викликають цю проблему. Коли маршрут провалюється, nginx не повертається до індексу.

Просто скопіюйте файл conf у потрібну папку: /etc/nginx/conf.d/default.conf

Приклад інструкції Dockerfile: COPY .docker/prod/nginx.conf /etc/nginx/conf.d/default.conf

Сподіваюся, це допомагає.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.