React-router và nginx


107

Tôi đang chuyển ứng dụng phản ứng của mình từ webpack-dev-server sang nginx.

Khi tôi truy cập url gốc "localhost: 8080 / login", tôi chỉ nhận được 404 và trong nhật ký nginx của mình, tôi thấy rằng nó đang cố lấy:

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

Tôi nên tìm cách sửa chữa ở đâu?

Bộ định tuyến bit trong phản ứng của tôi trông như thế này:

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

Và tệp nginx của tôi như thế này:

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


    }
}

BIÊN TẬP:

Tôi biết rằng hầu hết các thiết lập hoạt động vì khi tôi truy cập localhost: 8080 mà không đăng nhập, tôi cũng nhận được trang đăng nhập. điều này không thông qua chuyển hướng đến localhost: 8080 / login - nó là một số mã phản ứng.


1
Các tham số try_filesphải là URI chứ không phải tên đường dẫn. Hãy thử:try_files $uri $uri/ /index.html;
Richard Smith

@RichardSmith OK ... Tôi thấy nó là tên đường dẫn đến tệp index.html. Tôi đã thử thay đổi nó thành những gì bạn đề xuất - nhưng nhận được kết quả tương tự. ## / wwwroot / login "không thành công (2: Không có tệp hoặc thư mục như vậy) ## bạn có đề xuất khác không. Tôi sẽ đi sâu vào nó ...
martin

@martin bạn đã có thể giải quyết vấn đề này chưa? Chúng tôi đang thấy điều tương tự, nhưng đã có dòng try_files ở đó.
Billy Ferguson

Câu trả lời:


238

Khối vị trí trong cấu hình nginx của bạn phải là:

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

Vấn đề là các yêu cầu đến tệp index.html hoạt động, nhưng bạn hiện không yêu cầu nginx chuyển tiếp các yêu cầu khác tới tệp index.html.


8
Kiểm tra phần này để biết cấu hình nâng cao hơn (bộ nhớ đệm, 404 cho các tệp .js, .css bị thiếu, v.v.) gkedge.gitbooks.io/react-router-in-the-real/content/nginx.html
Gianfranco P.

Có vẻ như React Router không nên gây ra một chuyến đi vòng quanh máy chủ ... điều này có thể được ngăn chặn cục bộ không?
Scotty H

nếu nginx không định tuyến yêu cầu đến tệp index.html, thì JS bên trong Bộ định tuyến React thậm chí sẽ không bao giờ biết yêu cầu. Câu trả lời này định tuyến tất cả các yêu cầu đến React, cho phép React Router xử lý tất cả các yêu cầu.
Toby

Điều quan trọng nữa là sử dụng cài đặt trang chủ mặc định trong package.json, cài đặt này sử dụng máy chủ gốc. Tôi đã đặt nó thành '.', (Sử dụng đường dẫn tương đối), nhưng sau đó nginx đã cố gắng phân phát /custompath/static/main.js, điều này rõ ràng sẽ không thành công, tạo ra một trang web không hoạt động.
boerre

chỉ cần lưu ý, hãy đảm bảo rằng cấu hình của bạn thực sự đang được tải, của tôi đã xung đột với mặc định và đang bị bỏ qua. thở dài
4c74356b41

18

Đây là giải pháp của tôi

cố gắng đơn giản:

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

không cố gắng nữa cho các loại không phải 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;
}

không cố gắng nữa cho các loại và thư mục không phải html (làm cho try_filestương thích với indexvà / hoặc 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

Có thể đây không phải là trường hợp chính xác ở đây nhưng đối với bất kỳ ai đang chạy vùng dockerchứa cho reactdự án của họ react-routerwebpack-dev-server, trong trường hợp của tôi, tôi đã có mọi thứ tôi cần trong 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;
    }
  }

Nhưng nginx vẫn không gửi 404 erros đến thư mục gốc /. Sau khi xem xét vùng chứa, tôi nhận thấy rằng có một số cấu hình trong /etc/nginx/conf.d/default.confđó bằng cách nào đó sẽ ghi đè các cấu hình của tôi, vì vậy xóa tệp đó trong tôi đã dockerfilegiải quyết được vấn đề:

...
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
Bạn đã cứu ngày của tôi!
Bilal Hussain

4

Đây là giải pháp phù hợp với tôi trong máy chủ trực tiếp:

Tôi vừa làm theo hướng dẫn này và với cấu hình Nginx cơ bản chỉ cần cấu hình khối vị trí.

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

0

Đối với tôi, không có gì hoạt động cho đến khi tôi thêm một chỉ thị gốc. Điều này cũng hoạt động đối với tôi khi sử dụng proxy ngược để truy cập điểm cuối / api / webserver.

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

0

Tôi đã đối phó với cùng một vấn đề và tôi nghĩ rằng đó là một lỗi thông báo nhưng không. Tôi đang sao chép tệp conf vào /etc/nginx/conf.d/thư mục. Điều đó hoạt động trong nhà phát triển nhưng trong phiên bản xây dựng gây ra vấn đề đó. Khi định tuyến không thành công, nginx không dự phòng để lập chỉ mục.

Chỉ cần sao chép tệp conf vào đúng thư mục: /etc/nginx/conf.d/default.conf

Ví dụ về hướng dẫn Dockerfile: COPY .docker/prod/nginx.conf /etc/nginx/conf.d/default.conf

Hy vọng nó giúp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.