Score:0

nginx proxy_pass สำหรับตัวแทนผู้ใช้ที่กำหนด

ธง cn

ฉันมีเว็บไซต์ที่มี nginx ที่ส่งคืน index.html (แอปตอบกลับหน้าเดียว) สำหรับคำขอเกือบทั้งหมดคำขอใด ๆ สำหรับเกือบทุกเส้นทาง (เช่น /some/บทความ) ก็จะกลับมาเช่นกัน index.htmlและแอป react (react router) จะแปลพาธเป็นการเรียก API นี่คือวิธีการทำงาน และไม่สามารถเปลี่ยนแปลงได้ (เว็บไซต์มีขนาดใหญ่ ใช้งานมากเกินไป และฉันก็อยู่ในฐานะที่จะเปลี่ยนแปลงไม่ได้อยู่ดี)

ควรมีข้อยกเว้นสองประการสำหรับคำขอเหล่านี้:

  1. คำขอทั้งหมดที่เริ่มต้นด้วยเส้นทาง /api/* จะถูกส่งผ่านไปยังอัพสตรีม (เซิร์ฟเวอร์แอปพลิเคชัน) ดังนั้นแบ็กเอนด์อื่นจะจัดการคำขอ API จริงทั้งหมด
  2. ข้อยกเว้นอื่นควรเป็น facebook ภายนอกฮิต มีจุดสิ้นสุดที่แตกต่างกันภายใต้ /api/open_graph บนแอปพลิเคชันเซิร์ฟเวอร์สำหรับสิ่งนั้น เช่น. /api/open_graph ควรวางไว้ข้างหน้าเส้นทางเดิม จุดสิ้นสุดนั้นส่งคืนเนื้อหาจริง (และไม่ใช่แอปตอบโต้หน้าเดียวทั่วไปที่ไม่มีเนื้อหาจริง) รูปแบบก็แตกต่างกันเช่นกัน การเรียก API ปกติมักจะส่งคืนข้อมูล JSON แต่ปลายทาง open_graph ส่งคืน HTML แบบง่าย

ตัวอย่างการกำหนดค่า nginx:

ต้นน้ำ www {
    # ...
}

เซิร์ฟเวอร์ {
    # ...

    # ใช้ /api/open_graph บนอัปสตรีมสำหรับ facebook ภายนอกฮิต
    ถ้า ($http_user_agent ~* "^facebookexternalhit.*$") {
        เขียนใหม่ ^/(.*)$ /api/open_graph/$1 ถาวร;
    }

    # คำขอ API จะไปที่อัปสตรีม
    ตำแหน่ง ~ ^/api/ {
        proxy_pass http://www;
        proxy_read_timeout 90;
        proxy_redirect http://www https://example.com;
    }

    # คำขออื่น ๆ ทั้งหมดใช้แอปตอบสนอง
    # react เราเตอร์จัดการคำขอเพิ่มเติมทั้งหมด
    ที่ตั้ง / {
        ดัชนี index.html;
        error_page 404 =200 /index.html;
    }

}

การกำหนดค่าด้านบนทำงานดังนี้:

# curl -A "facebookexternalhit" -s -D - -o /dev/null https://example.com/article1
HTTP/1.1 301 ย้ายอย่างถาวร
เซิร์ฟเวอร์: nginx
วันที่: วันพุธที่ 20 ตุลาคม 2021 08:14:13 GMT
ประเภทเนื้อหา: text/html
ความยาวเนื้อหา: 162
ที่ตั้ง: https://example.com/api/open_graph/article1
การเชื่อมต่อ: มีชีวิตอยู่
เข้มงวด-การขนส่ง-ความปลอดภัย: max-age=31536000
X-Content-Type-Options: ไร้สาระ
X-XSS-การป้องกัน: 1; โหมด = บล็อก
ตัวเลือก X-Frame: SAMEORIGIN

เกือบดีแล้ว ยกเว้นว่ากราฟ API ของ Facebook ไม่รองรับการเปลี่ยนเส้นทาง (ใครจะรู้ว่าทำไม?) ดังนั้นแทนที่จะเปลี่ยนเส้นทางไปที่ /api/open_graph/* เซิร์ฟเวอร์ควรเชื่อมต่ออัปสตรีมโดยตรงและส่งต่อคำขอ

แต่ไม่รู้เป็นไง? ทางออกที่ไร้เดียงสาจะเป็น:

    # ใช้ /api/open_graph บนอัปสตรีมสำหรับ facebook ภายนอกฮิต
    ถ้า ($http_user_agent ~* "^facebookexternalhit.*$") {
        เขียนใหม่ ^/(.*)$ /api/open_graph/$1 ถาวร;
        proxy_pass http://www;
        proxy_read_timeout 90;
        proxy_redirect http://www https://example.com;
    }

แต่มันไม่ได้ผลเพราะ proxy_pass ใช้ได้เฉพาะภายในก ที่ตั้ง. ไม่สามารถใช้ภายใน ถ้า. ถ้าฉันลองกำหนดค่านั้น ฉันจะได้รับ:

nginx: [emerg] ไม่อนุญาตให้ใช้คำสั่ง "proxy_pass" ใน /etc/nginx/sites-enabled/example-www:62
nginx: การทดสอบไฟล์การกำหนดค่า /etc/nginx/nginx.conf ล้มเหลว

ฉันอาจเปลี่ยนรหัสโปรแกรมในอัปสตรีมได้ (เช่น เพิ่มตัวกรองสำหรับตัวแทนผู้ใช้ที่นั่น) แต่มันคงค่อนข้างยาก

มีวิธีแก้ปัญหาสำหรับสิ่งนี้ใน nginx หรือไม่

คำถามนี้เกี่ยวข้องกับ: nginx - proxy_pass บน user_agent แต่นั่นก็ไม่ได้ผลสำหรับฉันเช่นกัน (เกิดข้อผิดพลาด)

Richard Smith avatar
jp flag
ลองเปลี่ยนการกำหนดค่าดั้งเดิมของคุณจาก "ถาวร" เป็น "สุดท้าย"
Egidijus avatar
nz flag
เมื่อทำการดัดผมใน dev ให้ลองตั้งค่าสถานะเหล่านี้เพื่อเอาชนะใบรับรองที่ลงนามด้วยตนเอง ติดตามการเปลี่ยนเส้นทางและรับคุณค่ามากขึ้น: `curl -ivLk https://yahoo.com`

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา