React-router dan nginx

108

Saya sedang mentransisikan aplikasi react saya dari webpack-dev-server ke nginx.

Ketika saya membuka url root "localhost: 8080 / login" saya hanya mendapatkan 404 dan di log nginx saya, saya melihat bahwa itu mencoba untuk mendapatkan:

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" "-"

Di mana saya harus mencari perbaikan?

Bit router saya bereaksi terlihat seperti ini:

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);

Dan file nginx saya seperti ini:

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;
        }


    }
}

EDIT:

Saya tahu bahwa sebagian besar pengaturan berfungsi karena ketika saya pergi ke localhost: 8080 tanpa login saya mendapatkan halaman login juga. ini tidak melalui pengalihan ke localhost: 8080 / login - ini adalah beberapa kode reaksi.

martin
sumber
1
Parameter yang try_filesharus berupa URI dan bukan nama jalur. Coba:try_files $uri $uri/ /index.html;
Richard Smith
@RichardSmith Oke ... Saya melihatnya sebagai nama jalur ke file index.html. Saya telah mencoba mengubahnya menjadi apa yang Anda sarankan - tetapi mendapatkan hasil yang sama. ## / wwwroot / login "gagal (2: Tidak ada file atau direktori seperti itu) ## apakah Anda punya saran lain. Saya akan menyelami itu tonite ...
martin
@martin, apakah Anda sudah bisa menyelesaikan ini? Kami melihat hal yang sama, tetapi sudah memiliki baris try_files di sana.
Billy Ferguson

Jawaban:

242

Blok lokasi di konfigurasi nginx Anda harus:

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

Masalahnya adalah permintaan ke file index.html berfungsi, tetapi Anda saat ini tidak memberi tahu nginx untuk meneruskan permintaan lain ke file index.html juga.

Toby
sumber
8
Lihat ini untuk konfigurasi lanjutan (caching, 404 untuk file .js, .css yang hilang, dll.) Gkedge.gitbooks.io/react-router-in-the-real/content/nginx.html
Gianfranco P.
Sepertinya React Router seharusnya tidak menyebabkan perjalanan pulang pergi ke server sama sekali ... dapatkah ini terhalang secara lokal?
Scotty H
jika nginx tidak mengarahkan permintaan ke file index.html, maka JS di dalam React Router tidak akan pernah menyadari permintaan tersebut. Jawaban ini mengarahkan semua permintaan ke React, memungkinkan React Router untuk menangani semua permintaan.
Toby
Penting juga untuk menggunakan pengaturan beranda default di package.json, yang menggunakan root server. Saya telah mengaturnya ke '.', (Gunakan jalur relatif), tetapi kemudian nginx mencoba melayani /custompath/static/main.js, yang jelas akan gagal, memberikan situs yang tidak berfungsi.
boerre
tunggu dulu, pastikan konfigurasi Anda benar-benar sedang dimuat, konfigurasi saya bertentangan dengan default dan baru saja dilewati. menghela napas
4c74356b41
18

Inilah solusi saya

mencoba sederhana:

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

tidak perlu lagi mencoba jenis non-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;
}

tidak perlu lagi mencoba jenis dan direktori non-html (membuatnya try_fileskompatibel dengan indexdan / atau 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;
}
fuweichin
sumber
9

Mungkin ini bukan kasus yang tepat di sini tetapi untuk siapa pun yang menjalankan dockerwadah untuk reactproyek mereka dengan react-routerdan webpack-dev-server, dalam kasus saya, saya memiliki semua yang saya butuhkan di 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;
    }
  }

Tapi tetap saja nginx tidak akan mengirim 404 kesalahan ke root /. Setelah melihat ke dalam wadah, saya perhatikan bahwa ada beberapa konfigurasi /etc/nginx/conf.d/default.confyang entah bagaimana akan menimpa konfigurasi saya, jadi menghapus file itu di saya dockerfilememecahkan masalah:

...
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;"]
Alex Jolig
sumber
1
Anda menyelamatkan hari saya!
Bilal Hussain
4

Berikut adalah solusi yang berfungsi untuk saya di server langsung:

Saya baru saja mengikuti tutorial ini dan dengan konfigurasi Nginx dasar cukup mengkonfigurasi blok lokasi.

location / {
    try_files $uri $uri/ /index.html;
}
Fatema T. Zuhora
sumber
0

Bagi saya tidak ada yang berhasil sampai saya menambahkan arahan root. Ini berfungsi untuk saya juga menggunakan proxy terbalik untuk mencapai titik akhir / api / webserver.

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

Saya menghadapi masalah yang sama dan saya pikir itu adalah kesalahan conf tetapi tidak. Saya menyalin file conf ke /etc/nginx/conf.d/folder. Itu berfungsi di dev tetapi dalam versi build menyebabkan masalah itu. Jika rute gagal, nginx jangan fallback ke indeks.

Cukup salin file conf ke folder kanan: /etc/nginx/conf.d/default.conf

Contoh instruksi Dockerfile: COPY .docker/prod/nginx.conf /etc/nginx/conf.d/default.conf

Semoga membantu.

diogopalhais
sumber
-1
location / {
    root /path/to/root/directory/of/staticfiles;
    index index.html;
    try_files $uri /index.html;
}
sagarpatidar
sumber
Jawaban kode-saja tidak disarankan di Stack Overflow karena tidak menjelaskan cara menyelesaikan masalah. Harap edit jawaban Anda untuk menjelaskan apa yang dilakukan kode ini dan bagaimana meningkatkannya pada jawaban yang diberi suara positif yang ada, sehingga berguna bagi OP serta pengguna lain dengan masalah serupa.
FluffyKitten