fix(note): use relative redirect Location behind proxy
All checks were successful
Deploy eCourt Note Web to Server / Validate Database Schema (Drizzle) (push) Successful in 4s
Deploy eCourt Note Web to Server / Build Web Docker Image (push) Successful in 1m10s
Deploy eCourt Note Web to Server / Deploy eCourt Note Web to Server (push) Successful in 4s
Deploy eCourt Note Web to Server / Notify Deployment Status (push) Successful in 1s

หลัง reverse proxy ที่เขียนทับ Host เป็น upstream (nginx default
\$proxy_host เช่น 0.0.0.0:3000) การ 302 ด้วย NextResponse.redirect(
new URL(path, request.url)) ประกอบ absolute URL จาก origin ฝั่ง server
ทำให้บน prod กดลิงก์เปิดเอกสารตัวอย่างแล้ว browser ถูกพาไป
https://0.0.0.0:3000/docedit/note/annotate/... แทนโฮสต์จริง

เปลี่ยนเป็น Location แบบ relative (NextResponse + header เอง) ให้
browser resolve เทียบ origin ที่ตัวเองยิงมา — ถูกเสมอไม่ว่า proxy
จะตั้ง header แบบไหน:

- GET /api/note/files/open: 302 เข้า viewer และ 302 หน้าแรก
  กรณี fileError
- GET /api/note/auth/dev-link: 302 เข้า /note?fileUrl=…&t=…

ไม่แตะ dev-link POST ที่คืน {url} เต็ม — dev-only และลิงก์ต้อง
absolute เพื่อคัดลอกไปเปิดที่อื่น

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-11-02 11:12:11 +07:00
parent a288e5643c
commit 83a2cc3e5e
2 changed files with 14 additions and 6 deletions

View file

@ -62,9 +62,12 @@ export async function GET(request: Request): Promise<Response> {
// ปลายทาง = หน้าแรก /note พร้อม credential + fileUrl เหมือนลิงก์จริง — ให้ bootstrap
// ของ NoteHome แลกเป็น session token แล้วพาเข้า viewer (เห็น URL ทุกขั้นตอน)
const res = NextResponse.redirect(new URL(`${withBasePath("")}?${params.toString()}`, url), 302);
res.headers.set("cache-control", "no-store");
return res;
// Location relative เหมือน files/open — origin ของ request หลัง reverse proxy
// (Host ถูกเขียนทับเป็น upstream) ไม่น่าเชื่อพอจะประกอบ absolute URL
return new NextResponse(null, {
status: 302,
headers: { location: `${withBasePath("")}?${params.toString()}`, "cache-control": "no-store" },
});
}
export async function POST(request: Request): Promise<Response> {