React-router และ nginx


118

ฉันกำลังเปลี่ยนแอปตอบกลับจาก webpack-dev-server เป็น nginx

เมื่อฉันไปที่ root 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;
Richard Smith

@RichardSmith ตกลง ... ฉันเห็นมันเป็นชื่อพา ธ ไปยังไฟล์ index.html ฉันได้ลองเปลี่ยนเป็นสิ่งที่คุณแนะนำ - แต่ก็ได้ผลลัพธ์เหมือนกัน ## / wwwroot / login "ล้มเหลว (2: ไม่มีไฟล์หรือไดเร็กทอรีดังกล่าว) ## คุณมีคำแนะนำอื่น ๆ ไหมฉันจะดำดิ่งลงไปใน Tonite ...
martin

@martin คุณแก้ปัญหานี้ได้หรือยัง เราเห็นสิ่งเดียวกัน แต่มีบรรทัด try_files อยู่ที่นั่นแล้ว
Billy Ferguson

คำตอบ:


261

บล็อกตำแหน่งในการกำหนดค่า 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 หน้า

ดูเหมือนว่า React Router ไม่ควรทำให้เกิดการเดินทางไปกลับเซิร์ฟเวอร์เลย ... สิ่งนี้สามารถขัดขวางในเครื่องได้หรือไม่?
Scotty H

1
หาก nginx ไม่กำหนดเส้นทางการร้องขอไปยังไฟล์ index.html JS ใน React Router จะไม่รับรู้คำขอด้วยซ้ำ คำตอบนี้กำหนดเส้นทางการร้องขอทั้งหมดไปยัง React ทำให้ React Router จัดการกับคำขอทั้งหมด
Toby

สิ่งสำคัญคือต้องใช้การตั้งค่าหน้าแรกเริ่มต้นใน package.json ซึ่งใช้รูทเซิร์ฟเวอร์ ฉันตั้งค่าเป็น ".", (ใช้พา ธ สัมพัทธ์) แต่แล้ว nginx ก็พยายามให้บริการ /custompath/static/main.js ซึ่งเห็นได้ชัดว่าจะล้มเหลวโดยให้ไซต์ที่ไม่ทำงาน
boerre

1
เพียงแค่แจ้งให้แน่ใจว่าคุณกำลังโหลด config ของฉันขัดแย้งกับค่าเริ่มต้นและเพิ่งถูกข้ามไป ถอนหายใจ
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;
}

10

บางทีนี่อาจไม่ใช่กรณีที่แน่นอนที่นี่ แต่สำหรับใครก็ตามที่ใช้งาน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 erros ไปที่รู/ท หลังจากดูที่คอนเทนเนอร์แล้วฉันสังเกตเห็นว่ามีการกำหนดค่าบางอย่าง/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
คุณช่วยวันของฉัน!
Bilal Hussain

4

นี่คือวิธีแก้ปัญหาที่เหมาะกับฉันในเซิร์ฟเวอร์สด:

ฉันเพิ่งทำตามบทช่วยสอนนี้และด้วยการกำหนดค่า Nginx พื้นฐานเพียงแค่กำหนดค่าบล็อกตำแหน่ง

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

0

สำหรับฉันไม่มีอะไรทำงานจนกว่าฉันจะเพิ่มคำสั่งรูท สิ่งนี้ใช้ได้ผลสำหรับฉันโดยใช้ reverse proxy เพื่อตีจุดสิ้นสุด / api / webserver

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

0

นี่คือขั้นตอนบางส่วนที่ฉันทำซึ่งอาจช่วยได้หากคุณกำลังเริ่มต้น

  1. เมื่ออยู่ใน SSH จำเป็นต้องกลับไป/ใช้รูทโดยใช้cd ..คุณควรเข้ามา/
  2. จากนั้นค้นหาไฟล์. conf ที่มักจะอยู่ใน /etc/nginx/sites-available/{yoursitename or default}cd ด้านหน้าเพื่อไปที่ไฟล์นั้น
  3. แก้ไขไฟล์นั้นโดยใช้nanoหรือvimฉันใช้ Vim แบบนี้vi {your site.conf}
  4. นี่คือเนื้อหาของไฟล์ทั้งหมดที่ควรใช้งานได้
server {
        listen       80;
        server_name www.yourDomainName.com, yourDomainName.com;
        location / {
            root   /usr/share/nginx/{location of the build of your react project};
            index  index.html index.htm;
            
            try_files $uri $uri/ /index.html;

            passenger_enabled on;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}

0

Nginx จะพยายามค้นหา index.html ในรูทหากคุณใช้ตำแหน่งอื่นคุณอาจต้องเพิ่มลงในคำสั่ง try_files:

แทนที่จะเป็น:

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

คุณควรทำ:

location /MyLocation {
    root /var/www/html;
    try_files $uri /MyLocation/index.html; # Make sure to add the folder to the path
}

การเพิ่ม MyLocation ใน try_files คุณสร้าง nginx ให้ใช้ index.html ที่ถูกต้องเมื่อเปลี่ยนเส้นทาง


0

ฉันกำลังเผชิญกับปัญหาเดียวกันและฉันคิดว่านั่นเป็นข้อผิดพลาดที่เกิดขึ้น แต่ไม่ใช่ ฉันกำลังคัดลอกไฟล์ conf ไปยัง/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

หวังว่าจะช่วยได้


-1
location / {
    root /path/to/root/directory/of/staticfiles;
    index index.html;
    try_files $uri /index.html;
}

คำตอบแบบโค้ดเท่านั้นไม่แนะนำใน Stack Overflow เนื่องจากไม่ได้อธิบายว่าจะแก้ปัญหาอย่างไร โปรดแก้ไขคำตอบของคุณเพื่ออธิบายว่าโค้ดนี้ใช้ทำอะไรและปรับปรุงอย่างไรสำหรับคำตอบที่ได้รับการโหวตที่มีอยู่เพื่อให้เป็นประโยชน์กับ OP และผู้ใช้รายอื่นที่มีปัญหาคล้ายกัน
FluffyKitten
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.