Score:3

เป็นไปไม่ได้ที่จะมีส่วนหัวแบบมีเงื่อนไขใน Nginx?

ธง cn

ขณะนี้ฉันพยายามส่งคืนชุดของส่วนหัว CORS อย่างมีเงื่อนไขโดยใช้ Nginx ในตอนแรกดูเหมือนว่าจะเป็นงานง่ายๆ เนื่องจากฉันมีการกำหนดค่าการทำงานนี้อยู่แล้ว:

แอป API ต้นน้ำ {
  ยูนิกซ์เซิร์ฟเวอร์:/tmp/api-app.sock ล้มเหลว_timeout=0;
}

เซิร์ฟเวอร์ {
  ฟัง 80;
  # [สิ่งอื่น ๆ ของเซิร์ฟเวอร์...]

  # เพิ่มส่วนหัว CORS ในการตอบกลับทั้งหมดของเซิร์ฟเวอร์นี้ (จำเป็นสำหรับคำขอทั้งหมด)
  more_set_headers 'การเข้าถึง-การควบคุม-อนุญาต-วิธีการ: GET,POST,PATCH,PUT,DELETE,OPTIONS';
  more_set_headers 'เข้า-ควบคุม-อนุญาต-ต้นทาง: *';
  more_set_headers 'การควบคุมการเข้าถึง-อนุญาต-ข้อมูลประจำตัว: จริง';
  more_set_headers 'Access-Control-Request-Method: GET,POST,PATCH,PUT,DELETE,OPTIONS';
  more_set_headers 'Access-Control-Request-Headers: Content-Type';
  more_set_headers 'Access-Control-Allow-Headers: Origin,X-Requested-With,Content-Type,Accept,Session-Id,Role-Id,Visitor-Id,X-Window-Location';
  more_set_headers 'Access-Control-Expose-Headers: X-Total-Entries,X-Total-Pages,X-Page,X-Per-Page,X-Folder-Hierarchy';

  ที่ตั้ง / {
    # สำหรับคำขอ OPTIONS เท่านั้นที่ส่งคืนเหนือส่วนหัวและไม่มีเนื้อหา (อนุญาตให้แคชได้เช่นกัน)
    ถ้า ($request_method = 'ตัวเลือก') {
      # แคชเหนือส่วนหัว (การควบคุมการเข้าถึง)
      add_header 'Access-Control-Max-Age' 600;

      # กำหนดความยาวและประเภทของเนื้อหาเพื่อการวัดที่ดี:
      add_header 'ความยาวเนื้อหา' 0;
      add_header 'ประเภทเนื้อหา' 'ข้อความ/ชุดอักขระธรรมดา=UTF-8';

      # ส่งคืน 204 - ไม่มีเนื้อหา
      กลับ 204;
    }

    # ส่งต่อคำขอไปยังแอปจริง (หากเงื่อนไขทั้งหมดข้างต้นไม่ตรงกัน)
    proxy_set_header X-ส่งต่อ-สำหรับ $proxy_add_x_forwarded_for;
    proxy_set_header X-ส่งต่อโปรโต $http_x_forwarded_proto;
    proxy_set_header โฮสต์ $http_host;
    ปิด proxy_redirect;
    proxy_read_timeout 35;
    proxy_send_timeout 35;

    proxy_pass http://api-app;
  }
}

ดังนั้นฉันแค่ต้องการเปลี่ยนส่วนหัวของ CORS เป็น s.th แบบนี้

# ...
  ตั้ง $cors '';

  ถ้า ($http_origin ~ '^https?://(some.domain|some.other.domain|other-allows.domain)') {
      ตั้ง $cors 'จริง';
  }

  ถ้า ($cors = 'จริง') {
      more_set_headers 'การเข้าถึง-การควบคุม-อนุญาต-วิธีการ: GET,POST,PATCH,PUT,DELETE,OPTIONS';
      more_set_headers 'การเข้าถึง-การควบคุม-อนุญาต-ต้นทาง: $http_origin';
      more_set_headers 'การควบคุมการเข้าถึง-อนุญาต-ข้อมูลประจำตัว: จริง';
      more_set_headers 'Access-Control-Request-Method: GET,POST,PATCH,PUT,DELETE,OPTIONS';
      more_set_headers 'Access-Control-Request-Headers: Content-Type';
      more_set_headers 'Access-Control-Allow-Headers: Origin,X-Requested-With,Content-Type,Accept,Session-Id,Role-Id,Visitor-Id,X-Window-Location';
      more_set_headers 'Access-Control-Expose-Headers: X-Total-Entries,X-Total-Pages,X-Page,X-Per-Page,X-Folder-Hierarchy';
  }
  

  ที่ตั้ง / {
# ...

อย่างไรก็ตาม nginx -t รีบบอกฉัน more_set_headers ใช้ในคำสั่ง if ไม่ได้ ไม่สามารถ add_header ได้

ฉันพบว่าใน ที่ตั้ง ส่วนมันจะทำงาน แต่ฉันรู้แล้วว่านี่ไม่ใช่ทางออกที่ดีอย่างที่เราทุกคนรู้ ถ้าเป็นสิ่งชั่วร้ายในส่วนตำแหน่ง nginx. และฉันพูดถูกเพราะส่วนหัวของ CORS จะหายไปสำหรับคำขอ OPTIONS ฉันมี if case สำหรับ (อันที่ตกลงเพราะมันกลับมา)

ฉันเจอตัวเลือกในการใช้ Nginxs ด้วย ฟังก์ชั่นแผนที่. แต่จะใช้ได้ก็ต่อเมื่อฉันต้องการแก้ไขค่าส่วนหัว ไม่ใช่ถ้าฉันต้องการเพิ่มส่วนหัวทั้งบล็อก

ดังนั้นคำถามของฉันมีดังต่อไปนี้: มีวิธีเพิ่มส่วนหัวแบบมีเงื่อนไข (ไม่ใช้แผนที่) และนอกบล็อกตำแหน่งหรือไม่ เป็นการดีที่อนุญาตให้รวมส่วน CORS เพื่อให้ฉันสามารถใช้มันในเซิร์ฟเวอร์หลายเครื่อง (เช่นไซต์ nginx)

cn flag
เพื่อความสมบูรณ์ฉันพบวิธีแฮ็คในการทำงานนี้โดยการคัดลอกส่วน CORS ลงในส่วนตำแหน่ง (หากอนุญาต) และอีกครั้งในเงื่อนไข OTPIONS เพื่อส่งคืนส่วนหัว CORS ในกรณีนั้นด้วย แต่ฉันไม่ต้องการ เพื่อใช้สิ่งนี้ในการผลิต :P
Score:3
ธง us

ฉันไม่รู้ว่าถ้า more_set_headers ยอมรับสตริงว่าง หากยอมรับ คุณสามารถกำหนดได้หลายรายการ แผนที่ ข้อความ:

แผนที่ $http_origin $cors_methods {
    ค่าเริ่มต้น "";
    ~^https?://(some.domain|some.other.domain|other-allows.domain) Access-Control-Allow-Methods: GET,POST,PATCH,PUT,DELETE,OPTIONS;
}

แผนที่ $http_origin $cors_origin {
    ค่าเริ่มต้น "";
    ~^https?://(some.domain|some.other.domain|other-allows.domain) Access-Control-Allow-Origin: $http_origin;
}

แล้วใช้สิ่งนี้:

more_set_headers $cors_methods;
more_set_headers $cors_origin;
cn flag
ใช่ นั่นคือสิ่งที่ฉันพยายามพูดถึงด้วยฟังก์ชันแผนที่ อย่างไรก็ตาม ฉันหวังว่าจะมีวิธีที่ง่ายกว่าในการเปิด/ปิดส่วนหัวทั้งหมดในคราวเดียว แต่คงไม่มี
cn flag
นอกจากนี้ฉันเพิ่งรู้ว่าไม่สามารถใช้ฟังก์ชั่นแผนที่ในบล็อกเซิร์ฟเวอร์ได้เฉพาะในบล็อก http
us flag
ใช่ ต้องกำหนด `แผนที่` ในระดับ `http` แต่นั่นจะไม่ส่งผลต่อประโยชน์ของมัน

โพสต์คำตอบ

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