Nginx ทำงานบนพอร์ต 80 และฉันใช้เพื่อย้อนกลับ URL ของพร็อกซีด้วยเส้นทาง/fooไปยังพอร์ต3200ด้วยวิธีนี้:

location /foo {
                proxy_pass http://localhost:3200;
                proxy_redirect     off;
                proxy_set_header   Host $host;
}

ใช้งานได้ดี แต่ฉันมีแอปพลิเคชันบน port 3200ซึ่งฉันไม่ต้องการ/fooให้ส่งชื่อย่อไป นั่นคือ - เมื่อฉันเข้าถึงhttp://localhost/foo/barฉันต้องการเพียง/barเส้นทางที่แอปได้รับเท่านั้น ดังนั้นฉันจึงลองเพิ่มบรรทัดนี้ในบล็อกตำแหน่งด้านบน:

rewrite ^(.*)foo(.*)$ http://localhost:3200/$2 permanent;

ทำให้เกิดการเปลี่ยนเส้นทาง 302 (เปลี่ยนใน URL) แต่ฉันต้องการ 301 ฉันควรทำอย่างไร

answer

การเปลี่ยนเส้นทางไปยัง localhost ไม่สมเหตุสมผลจากระบบระยะไกล (เช่น เว็บเบราว์เซอร์ของลูกค้า) ดังนั้นการตั้งค่าสถานะการเขียนซ้ำแบบถาวร (301) หรือการเปลี่ยนเส้นทาง (302) จึงไม่สามารถใช้ได้ในกรณีของคุณ

โปรดลองตั้งค่าตามนี้โดยใช้กฎการเขียนซ้ำที่โปร่งใส:

location  /foo {
  rewrite /foo/(.*) /$1  break;
  proxy_pass         http://localhost:3200;
  proxy_redirect     off;
  proxy_set_header   Host $host;
}

ใช้curl -iเพื่อทดสอบการเขียนใหม่ของคุณ การเปลี่ยนแปลงกฎเพียงเล็กน้อยอาจทำให้ nginx ทำการเปลี่ยนเส้นทางได้

การจับคู่คำนำหน้าตำแหน่งอย่างง่ายใช้งานได้โดยไม่ต้องใช้กฎการเขียนซ้ำ ตราบใดที่คุณระบุ URI ในคำสั่ง proxy_pass:

location /foo {
  proxy_pass http://localhost:3200/;
}

สังเกตเพิ่มเติม/ที่ส่วนท้ายของproxy_passคำสั่ง NGINX จะตัดคำนำหน้าจับคู่/fooและผ่านที่เหลือไปยังเซิร์ฟเวอร์แบ็กเอนด์ที่ /URI ดังนั้นจะโพสต์ไปที่แบ็กเอนด์http://myserver:80/foo/barhttp://localhost:3200/bar

จากเอกสาร NGINX บน proxy_pass :

If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive:

วิธีที่ถูกต้องที่สุดและแนวปฏิบัติที่ดีที่สุดมักจะเป็นดังนี้:

location /foo/ {
    proxy_pass http://localhost:3200/; # note the trailing slash!
}

  • สังเกตความสำคัญอย่างยิ่งของเครื่องหมายทับในproxy_passซึ่งจะเปลี่ยน$uriตัวแปรโดยอัตโนมัติเพื่อให้/foo/ส่วนหน้าสอดคล้องกับ/ส่วนหลัง ไม่จำเป็นต้องมีrewriteคำสั่งที่ชัดเจน

  • นอกจากนี้ โปรดทราบว่าการต่อท้าย/ในนั้นlocationก็ค่อนข้างสำคัญเช่นกัน หากไม่มี คุณอาจเสี่ยงที่จะมี URL ที่ดูแปลก ๆ บนไซต์ของคุณ ณ จุดหนึ่ง (เช่น การทำงาน/fooenเพิ่มเติมจาก/foo/en)

    นอกจากนี้ การต่อท้าย/ในlocationwith proxy_passยังช่วยให้มั่นใจถึงการจัดการพิเศษบางอย่างตามเอกสารของlocationคำสั่ง เพื่อทำให้เกิดผลโดยปริยายlocation = /foo {return 301 /foo/;}เช่นกัน

    ดังนั้น โดยการกำหนด a locationด้วยเครื่องหมายทับตามด้านบน คุณไม่เพียงแต่ทำให้แน่ใจว่า URL ต่อท้ายแบบ/fooenไม่มีเครื่องหมายทับดังกล่าวจะไม่ถูกต้อง แต่ยังรวมถึง a ที่/fooไม่มีเครื่องหมายทับจะยังคงทำงานต่อไปอีกด้วย


เอกสารอ้างอิง:

ลอง

location /foo {
    proxy_pass http://localhost:3200/;
    ....

หรือ

location ^~ /foo {
    proxy_pass http://localhost:3200/;
    ....

@Terabuck ขออภัยที่ยังไม่ได้ตอบกลับไม่มีตัวแทน

คุณไม่ควรใช้ localhost เนื่องจากคุณขึ้นอยู่กับความจริงที่ว่าแอปพลิเคชันกำลังทำงานบนเซิร์ฟเวอร์ที่มีไฟล์โฮสต์ โฮสต์ท้องถิ่นเป็นเพียงการแปลเริ่มต้นเป็น 127.0.0.1 ไม่มีอะไรที่ระบุว่าคุณต้องมีไฟล์โฮสต์นี้ มันเป็นเรื่องธรรมดามากที่จะมี

การมีอินเทอร์เฟซแบบวนรอบเป็นอีกสิ่งหนึ่งที่ต้องพึ่งพาอาศัยกันทั่วไป แต่คุณยังคงต้องพึ่งพาอินเทอร์เฟซแบบวนรอบบนสแต็กเครือข่าย หายากมากที่จะไม่มีสองสิ่งนี้ หากคุณเคยกังวลเกี่ยวกับเรื่องนี้ อย่างน้อยบน unix/linux คุณมีตัวเลือกสำหรับซ็อกเก็ต สิ่งนี้จะขจัดความจำเป็นสำหรับสแต็กเครือข่ายในการเข้าถึงโลคัลโฮสต์ ใช้ความระมัดระวังด้วยวิธีนี้ เนื่องจากมีปัจจัยบางประการที่จะเกิดขึ้นในระบบปฏิบัติการโฮสต์ เช่นจำนวนไฟล์ที่เปิดอยู่ เป็นต้น