Web interfaces

ส่วนติดต่อผู้ใช้สำหรับควบคุม

Control UI คือแอปหน้าเดียวขนาดเล็กแบบ Vite + Lit ที่ให้บริการโดย Gateway:

  • ค่าเริ่มต้น: http://<host>:18789/
  • คำนำหน้าเพิ่มเติม: ตั้งค่า gateway.controlUi.basePath (เช่น /openclaw)

แอปนี้สื่อสาร โดยตรงกับ Gateway WebSocket บนพอร์ตเดียวกัน

เปิดอย่างรวดเร็ว (ภายในเครื่อง)

หาก Gateway กำลังทำงานอยู่บนคอมพิวเตอร์เครื่องเดียวกัน ให้เปิด:

หากหน้าโหลดไม่สำเร็จ ให้เริ่ม Gateway ก่อน: openclaw gateway

มีการส่งข้อมูลยืนยันตัวตนระหว่าง WebSocket handshake ผ่าน:

  • connect.params.auth.token
  • connect.params.auth.password
  • ส่วนหัวระบุตัวตนของ Tailscale Serve เมื่อ gateway.auth.allowTailscale: true
  • ส่วนหัวระบุตัวตนของพร็อกซีที่เชื่อถือได้เมื่อ gateway.auth.mode: "trusted-proxy"

แผงการตั้งค่าของแดชบอร์ดเก็บโทเค็นไว้สำหรับเซสชันแท็บเบราว์เซอร์ปัจจุบันและ URL ของ Gateway ที่เลือกไว้ โดยจะไม่จัดเก็บรหัสผ่านไว้ Onboarding มักจะสร้างโทเค็น Gateway สำหรับการยืนยันตัวตนแบบ shared-secret ในการเชื่อมต่อครั้งแรก แต่การยืนยันตัวตนด้วยรหัสผ่านก็ใช้งานได้เช่นกันเมื่อ gateway.auth.mode เป็น "password"

การจับคู่อุปกรณ์ (การเชื่อมต่อครั้งแรก)

เมื่อคุณเชื่อมต่อกับ Control UI จากเบราว์เซอร์หรืออุปกรณ์ใหม่ Gateway มักจะต้องการ การอนุมัติการจับคู่แบบครั้งเดียว นี่เป็นมาตรการรักษาความปลอดภัยเพื่อป้องกันการเข้าถึงที่ไม่ได้รับอนุญาต

สิ่งที่คุณจะเห็น: "disconnected (1008): pairing required"

  • แสดงคำขอที่รอดำเนินการ

    openclaw devices list
    
  • อนุมัติด้วย ID คำขอ

    openclaw devices approve <requestId>
    
  • หากเบราว์เซอร์ลองจับคู่อีกครั้งด้วยรายละเอียดการยืนยันตัวตนที่เปลี่ยนไป (บทบาท/ขอบเขต/กุญแจสาธารณะ) คำขอที่รอดำเนินการก่อนหน้าจะถูกแทนที่ และจะสร้าง requestId ใหม่ ให้รัน openclaw devices list อีกครั้งก่อนอนุมัติ

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

    เมื่ออนุมัติแล้ว ระบบจะจดจำอุปกรณ์นั้นและจะไม่ต้องอนุมัติใหม่ เว้นแต่คุณจะเพิกถอนด้วย openclaw devices revoke --device <id> --role <role> ดู CLI สำหรับอุปกรณ์ สำหรับการหมุนเวียนและเพิกถอนโทเค็น

    ตัวตนส่วนบุคคล (เฉพาะเบราว์เซอร์)

    Control UI รองรับตัวตนส่วนบุคคลต่อเบราว์เซอร์ (ชื่อที่แสดงและอวาตาร์) ที่แนบไปกับข้อความขาออกเพื่อระบุผู้ส่งในเซสชันที่ใช้ร่วมกัน ตัวตนนี้อยู่ในพื้นที่จัดเก็บของเบราว์เซอร์ ถูกจำกัดขอบเขตไว้กับโปรไฟล์เบราว์เซอร์ปัจจุบัน และไม่ซิงก์ไปยังอุปกรณ์อื่นหรือจัดเก็บถาวรฝั่งเซิร์ฟเวอร์ นอกเหนือจากเมตาดาต้าผู้เขียนทรานสคริปต์ตามปกติบนข้อความที่คุณส่งจริง การล้างข้อมูลไซต์หรือสลับเบราว์เซอร์จะรีเซ็ตให้ว่างเปล่า

    รูปแบบเฉพาะเบราว์เซอร์เดียวกันนี้ใช้กับการแทนที่อวาตาร์ของผู้ช่วยด้วย อวาตาร์ผู้ช่วยที่อัปโหลดจะซ้อนทับตัวตนที่ Gateway ระบุได้เฉพาะบนเบราว์เซอร์ภายในเครื่องเท่านั้น และจะไม่ส่งไปกลับผ่าน config.patch ฟิลด์คอนฟิกที่ใช้ร่วมกัน ui.assistant.avatar ยังมีอยู่สำหรับไคลเอนต์ที่ไม่ใช่ UI ซึ่งเขียนฟิลด์นี้โดยตรง (เช่น Gateway ที่สคริปต์ไว้หรือแดชบอร์ดแบบกำหนดเอง)

    Endpoint คอนฟิกขณะรัน

    Control UI ดึงการตั้งค่าขณะรันจาก /__openclaw/control-ui-config.json Endpoint นั้นถูกป้องกันด้วยการยืนยันตัวตน Gateway แบบเดียวกับพื้นผิว HTTP ส่วนที่เหลือ: เบราว์เซอร์ที่ไม่ได้ยืนยันตัวตนจะไม่สามารถดึงข้อมูลได้ และการดึงข้อมูลที่สำเร็จต้องมีโทเค็น/รหัสผ่าน Gateway ที่ถูกต้องอยู่แล้ว ตัวตน Tailscale Serve หรือตัวตนของพร็อกซีที่เชื่อถือได้

    การรองรับภาษา

    Control UI สามารถแปลภาษาตัวเองในการโหลดครั้งแรกตาม locale ของเบราว์เซอร์ของคุณ หากต้องการเขียนทับในภายหลัง ให้เปิด ภาพรวม -> การเข้าถึง Gateway -> ภาษา ตัวเลือก locale อยู่ในการ์ดการเข้าถึง Gateway ไม่ใช่ภายใต้รูปลักษณ์

    • Locale ที่รองรับ: en, zh-CN, zh-TW, pt-BR, de, es, ja-JP, ko, fr, ar, it, tr, uk, id, pl, th, vi, nl, fa
    • คำแปลที่ไม่ใช่ภาษาอังกฤษจะถูกโหลดแบบ lazy-load ในเบราว์เซอร์
    • Locale ที่เลือกจะถูกบันทึกในพื้นที่จัดเก็บของเบราว์เซอร์และนำกลับมาใช้ในการเข้าชมครั้งถัดไป
    • คีย์คำแปลที่ขาดหายจะ fallback เป็นภาษาอังกฤษ

    คำแปลเอกสารถูกสร้างสำหรับชุด locale ที่ไม่ใช่ภาษาอังกฤษเดียวกัน แต่ตัวเลือกภาษาในตัวของไซต์เอกสารของ Mintlify จำกัดอยู่เฉพาะรหัส locale ที่ Mintlify ยอมรับ เอกสารภาษาไทย (th) และเปอร์เซีย (fa) ยังคงถูกสร้างใน publish repo แต่อาจไม่ปรากฏในตัวเลือกนั้นจนกว่า Mintlify จะรองรับรหัสเหล่านั้น

    ธีมรูปลักษณ์

    แผงรูปลักษณ์เก็บธีม Claw, Knot และ Dash ในตัวไว้ รวมถึงช่องนำเข้า tweakcn แบบเฉพาะเบราว์เซอร์อีกหนึ่งช่อง หากต้องการนำเข้าธีม ให้เปิด ตัวแก้ไข tweakcn เลือกหรือสร้างธีม คลิก แชร์ แล้ววางลิงก์ธีมที่คัดลอกมาในรูปลักษณ์ ตัวนำเข้ายังยอมรับ URL รีจิสทรี https://tweakcn.com/r/themes/<id>, URL ตัวแก้ไขเช่น https://tweakcn.com/editor/theme?theme=amethyst-haze, พาธสัมพัทธ์ /themes/<id>, ID ธีมดิบ และชื่อธีมเริ่มต้น เช่น amethyst-haze

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

    สิ่งที่ทำได้ (ตอนนี้)

    แชตและพูดคุย
    • แชตกับโมเดลผ่าน Gateway WS (chat.history, chat.send, chat.abort, chat.inject)
    • การรีเฟรชประวัติแชตจะขอหน้าต่างล่าสุดแบบจำกัดพร้อมเพดานข้อความต่อข้อความ เพื่อให้เซสชันขนาดใหญ่ไม่บังคับให้เบราว์เซอร์เรนเดอร์ payload ทรานสคริปต์ทั้งหมดก่อนที่แชตจะใช้งานได้
    • พูดคุยผ่านเซสชันเรียลไทม์ของเบราว์เซอร์ OpenAI ใช้ WebRTC โดยตรง, Google Live ใช้โทเค็นเบราว์เซอร์แบบใช้ครั้งเดียวที่มีข้อจำกัดผ่าน WebSocket และ Plugin เสียงเรียลไทม์แบบ backend-only ใช้การขนส่งผ่านรีเลย์ของ Gateway เซสชันผู้ให้บริการที่ไคลเอนต์เป็นเจ้าของเริ่มด้วย talk.client.create; เซสชันรีเลย์ Gateway เริ่มด้วย talk.session.create รีเลย์เก็บข้อมูลประจำตัวของผู้ให้บริการไว้บน Gateway ขณะที่เบราว์เซอร์สตรีม PCM จากไมโครโฟนผ่าน talk.session.appendAudio และส่งต่อการเรียกเครื่องมือของผู้ให้บริการ openclaw_agent_consult ผ่าน talk.client.toolCall สำหรับนโยบาย Gateway และโมเดล OpenClaw ที่กำหนดค่าขนาดใหญ่กว่า
    • สตรีมการเรียกเครื่องมือ + การ์ดเอาต์พุตเครื่องมือสดในแชต (เหตุการณ์เอเจนต์)
    ช่องทาง อินสแตนซ์ เซสชัน ความฝัน
    • ช่องทาง: สถานะช่องทางในตัวและช่องทาง Plugin แบบ bundled/ภายนอก, การเข้าสู่ระบบด้วย QR และคอนฟิกต่อช่องทาง (channels.status, web.login.*, config.patch)
    • การรีเฟรชการตรวจสอบช่องทางจะคงสแนปช็อตก่อนหน้าให้มองเห็นได้ในขณะที่การตรวจสอบผู้ให้บริการที่ช้ากำลังเสร็จสิ้น และสแนปช็อตบางส่วนจะถูกติดป้ายเมื่อการ probe หรือ audit เกินงบเวลา UI
    • อินสแตนซ์: รายการ presence + รีเฟรช (system-presence)
    • เซสชัน: แสดงรายการเซสชันของเอเจนต์ที่กำหนดค่าไว้เป็นค่าเริ่มต้น, fallback จากคีย์เซสชันเอเจนต์ที่ไม่ได้กำหนดค่าซึ่งล้าสมัย และใช้การเขียนทับโมเดล/thinking/fast/verbose/trace/reasoning ต่อเซสชัน (sessions.list, sessions.patch)
    • ความฝัน: สถานะ Dreaming, toggle เปิด/ปิด และตัวอ่าน Dream Diary (doctor.memory.status, doctor.memory.dreamDiary, config.patch)
    Cron, Skills, Node, การอนุมัติ exec
    • งาน Cron: แสดงรายการ/เพิ่ม/แก้ไข/รัน/เปิดใช้/ปิดใช้ + ประวัติการรัน (cron.*)
    • Skills: สถานะ, เปิดใช้/ปิดใช้, ติดตั้ง, อัปเดต API key (skills.*)
    • Node: รายการ + caps (node.list)
    • การอนุมัติ exec: แก้ไข allowlist ของ Gateway หรือ Node + นโยบายการถามสำหรับ exec host=gateway/node (exec.approvals.*)
    คอนฟิก
    • ดู/แก้ไข ~/.openclaw/openclaw.json (config.get, config.set)
    • ใช้งาน + รีสตาร์ตพร้อมการตรวจสอบความถูกต้อง (config.apply) และปลุกเซสชันที่ใช้งานล่าสุด
    • การเขียนมีการป้องกันด้วย base-hash เพื่อป้องกันการเขียนทับการแก้ไขพร้อมกัน
    • การเขียน (config.set/config.apply/config.patch) จะ preflight การแก้ไข SecretRef ที่ active สำหรับ refs ใน payload คอนฟิกที่ส่งมา; refs ที่ active และส่งมาซึ่งแก้ไขไม่ได้จะถูกปฏิเสธก่อนเขียน
    • การเรนเดอร์ schema + ฟอร์ม (config.schema / config.schema.lookup รวมถึง title / description ของฟิลด์, คำใบ้ UI ที่จับคู่, สรุปลูกโดยตรง, เมตาดาต้าเอกสารบนโหนด object/wildcard/array/composition แบบซ้อน รวมถึง schema ของ Plugin + ช่องทางเมื่อมี); ตัวแก้ไข JSON ดิบมีให้ใช้เฉพาะเมื่อสแนปช็อตมี raw round-trip ที่ปลอดภัย
    • หากสแนปช็อตไม่สามารถ round-trip ข้อความดิบได้อย่างปลอดภัย Control UI จะบังคับใช้โหมดฟอร์มและปิดโหมดดิบสำหรับสแนปช็อตนั้น
    • "รีเซ็ตเป็นที่บันทึกไว้" ในตัวแก้ไข JSON ดิบจะคงรูปทรงที่เขียนแบบดิบไว้ (การจัดรูปแบบ, ความคิดเห็น, layout ของ $include) แทนการเรนเดอร์สแนปช็อตแบบ flatten ใหม่ เพื่อให้การแก้ไขจากภายนอกยังอยู่รอดหลังรีเซ็ตเมื่อสแนปช็อตสามารถ round-trip ได้อย่างปลอดภัย
    • ค่าอ็อบเจกต์ SecretRef แบบมีโครงสร้างจะแสดงเป็นอ่านอย่างเดียวในช่องข้อความของฟอร์ม เพื่อป้องกันความเสียหายจากการแปลงอ็อบเจกต์เป็นสตริงโดยไม่ตั้งใจ
    ดีบัก ล็อก อัปเดต
    • ดีบัก: สแนปช็อตสถานะ/สุขภาพ/โมเดล + บันทึกเหตุการณ์ + การเรียก RPC ด้วยตนเอง (status, health, models.list)
    • บันทึกเหตุการณ์รวมเวลารีเฟรช/RPC ของ Control UI, เวลาเรนเดอร์แชต/คอนฟิกที่ช้า และรายการความตอบสนองของเบราว์เซอร์สำหรับเฟรมแอนิเมชันยาวหรืองานยาวเมื่อเบราว์เซอร์เปิดเผยชนิดรายการ PerformanceObserver เหล่านั้น
    • ล็อก: tail สดของล็อกไฟล์ Gateway พร้อมตัวกรอง/ส่งออก (logs.tail)
    • อัปเดต: รันการอัปเดตแพ็กเกจ/git + รีสตาร์ต (update.run) พร้อมรายงานการรีสตาร์ต จากนั้น poll update.status หลังเชื่อมต่อใหม่เพื่อตรวจสอบเวอร์ชัน Gateway ที่กำลังทำงาน
    หมายเหตุแผงงาน Cron
    • สำหรับงานแบบแยก การส่งมอบจะมีค่าเริ่มต้นเป็นการประกาศสรุป คุณสามารถเปลี่ยนเป็นไม่มีได้หากต้องการให้เป็นการรันภายในเท่านั้น
    • ฟิลด์ช่องทาง/เป้าหมายจะปรากฏเมื่อเลือกประกาศ
    • โหมด Webhook ใช้ delivery.mode = "webhook" โดยตั้งค่า delivery.to เป็น URL Webhook HTTP(S) ที่ถูกต้อง
    • สำหรับงานเซสชันหลัก สามารถใช้โหมดการส่งมอบแบบ Webhook และไม่มีได้
    • ตัวควบคุมการแก้ไขขั้นสูงรวมถึง delete-after-run, ล้างการเขียนทับเอเจนต์, ตัวเลือก cron exact/stagger, การเขียนทับโมเดล/thinking ของเอเจนต์ และ toggle การส่งมอบแบบ best-effort
    • การตรวจสอบความถูกต้องของฟอร์มอยู่แบบ inline พร้อมข้อผิดพลาดระดับฟิลด์; ค่าที่ไม่ถูกต้องจะปิดปุ่มบันทึกจนกว่าจะแก้ไข
    • ตั้งค่า cron.webhookToken เพื่อส่ง bearer token เฉพาะ หากละไว้ Webhook จะถูกส่งโดยไม่มีส่วนหัว auth
    • fallback ที่เลิกใช้แล้ว: งาน legacy ที่จัดเก็บไว้พร้อม notify: true ยังสามารถใช้ cron.webhook ได้จนกว่าจะ migrate

    พฤติกรรมแชต

    ความหมายของการส่งและประวัติ
    • chat.send เป็นแบบ ไม่บล็อก: ตอบรับทันทีด้วย { runId, status: "started" } และสตรีมการตอบกลับผ่านเหตุการณ์ chat
    • การอัปโหลดแชตรองรับรูปภาพพร้อมไฟล์ที่ไม่ใช่วิดีโอ รูปภาพจะคงพาธรูปภาพดั้งเดิมไว้ ส่วนไฟล์อื่นจะถูกจัดเก็บเป็นสื่อที่จัดการแล้วและแสดงในประวัติเป็นลิงก์ไฟล์แนบ
    • การส่งซ้ำด้วย idempotencyKey เดิมจะคืนค่า { status: "in_flight" } ระหว่างที่กำลังทำงาน และ { status: "ok" } หลังเสร็จสิ้น
    • การตอบกลับของ chat.history ถูกจำกัดขนาดเพื่อความปลอดภัยของ UI เมื่อรายการทรานสคริปต์ใหญ่เกินไป Gateway อาจตัดฟิลด์ข้อความยาวออก ละเว้นบล็อกเมตาดาต้าที่หนัก และแทนที่ข้อความที่ใหญ่เกินด้วยตัวแทน ([chat.history omitted: message too large])
    • รูปภาพจากผู้ช่วย/ที่สร้างขึ้นจะถูกคงไว้เป็นการอ้างอิงสื่อที่จัดการแล้ว และให้บริการกลับผ่าน URL สื่อของ Gateway ที่ผ่านการยืนยันตัวตน ดังนั้นการโหลดซ้ำจึงไม่ขึ้นกับเพย์โหลดรูปภาพ base64 ดิบที่ยังอยู่ในการตอบกลับประวัติแชต
    • เมื่อเรนเดอร์ chat.history Control UI จะลบแท็กคำสั่งอินไลน์ที่มีไว้เพื่อการแสดงผลเท่านั้นออกจากข้อความผู้ช่วยที่มองเห็นได้ (เช่น [[reply_to_*]] และ [[audio_as_voice]]), เพย์โหลด XML ของการเรียกเครื่องมือแบบข้อความธรรมดา (รวมถึง <tool_call>...</tool_call>, <function_call>...</function_call>, <tool_calls>...</tool_calls>, <function_calls>...</function_calls> และบล็อกการเรียกเครื่องมือที่ถูกตัดทอน), โทเค็นควบคุมโมเดล ASCII/แบบเต็มความกว้างที่รั่วออกมา และละเว้นรายการผู้ช่วยที่ข้อความที่มองเห็นทั้งหมดเป็นเพียงโทเค็นเงียบแบบตรงตัว NO_REPLY / no_reply หรือโทเค็นตอบรับ Heartbeat HEARTBEAT_OK
    • ระหว่างการส่งที่ทำงานอยู่และการรีเฟรชประวัติครั้งสุดท้าย มุมมองแชตจะเก็บข้อความผู้ใช้/ผู้ช่วยแบบคาดการณ์ในเครื่องให้มองเห็นต่อไป หาก chat.history คืนสแนปชอตที่เก่ากว่าเป็นช่วงสั้น ๆ ทรานสคริปต์มาตรฐานจะแทนที่ข้อความในเครื่องเหล่านั้นเมื่อประวัติ Gateway ตามทัน
    • เหตุการณ์ chat สดคือสถานะการส่งมอบ ส่วน chat.history ถูกสร้างใหม่จากทรานสคริปต์เซสชันที่คงทน หลังเหตุการณ์ tool-final Control UI จะโหลดประวัติซ้ำและรวมเฉพาะส่วนท้ายแบบคาดการณ์ขนาดเล็ก ขอบเขตทรานสคริปต์มีเอกสารไว้ใน WebChat
    • chat.inject เพิ่มบันทึกของผู้ช่วยต่อท้ายทรานสคริปต์เซสชันและกระจายเหตุการณ์ chat สำหรับการอัปเดตเฉพาะ UI (ไม่มีการรันเอเจนต์ ไม่มีการส่งมอบช่องทาง)
    • ส่วนหัวแชตแสดงตัวกรองเอเจนต์ก่อนตัวเลือกเซสชัน และตัวเลือกเซสชันถูกจำกัดขอบเขตตามเอเจนต์ที่เลือก การสลับเอเจนต์จะแสดงเฉพาะเซสชันที่ผูกกับเอเจนต์นั้น และย้อนกลับไปยังเซสชันหลักของเอเจนต์นั้นเมื่อยังไม่มีเซสชันแดชบอร์ดที่บันทึกไว้
    • บนความกว้างเดสก์ท็อป ตัวควบคุมแชตจะอยู่ในแถวกะทัดรัดแถวเดียวและยุบเมื่อเลื่อนลงในทรานสคริปต์ การเลื่อนขึ้น กลับไปด้านบน หรือไปถึงด้านล่างจะคืนตัวควบคุมกลับมา
    • ข้อความข้อความล้วนที่ซ้ำต่อเนื่องจะแสดงเป็นบับเบิลเดียวพร้อมป้ายจำนวน ข้อความที่มีรูปภาพ ไฟล์แนบ เอาต์พุตเครื่องมือ หรือพรีวิวแคนวาสจะไม่ถูกยุบ
    • ตัวเลือกโมเดลและการคิดในส่วนหัวแชตจะแพตช์เซสชันที่ใช้งานทันทีผ่าน sessions.patch; สิ่งเหล่านี้เป็นการโอเวอร์ไรด์เซสชันแบบคงอยู่ ไม่ใช่ตัวเลือกการส่งสำหรับเทิร์นเดียวเท่านั้น
    • การพิมพ์ /new ใน Control UI จะสร้างและสลับไปยังเซสชันแดชบอร์ดใหม่เดียวกับ New Chat การพิมพ์ /reset จะคงการรีเซ็ตในตำแหน่งเดิมแบบชัดเจนของ Gateway สำหรับเซสชันปัจจุบัน
    • ตัวเลือกโมเดลแชตขอมุมมองโมเดลที่กำหนดค่าของ Gateway หากมี agents.defaults.models รายการอนุญาตนั้นจะขับเคลื่อนตัวเลือก มิฉะนั้นตัวเลือกจะแสดงรายการ models.providers.*.models ที่ชัดเจนพร้อมผู้ให้บริการที่มีการยืนยันตัวตนที่ใช้งานได้ แค็ตตาล็อกเต็มยังคงพร้อมใช้งานผ่าน RPC ดีบัก models.list พร้อม view: "all"
    • เมื่อรายงานการใช้งานเซสชัน Gateway สดรวมโทเค็นบริบทปัจจุบัน พื้นที่ตัวเขียนแชตจะแสดงตัวบ่งชี้การใช้งานบริบทแบบกะทัดรัด ตัวบ่งชี้จะสลับเป็นสไตล์เตือนเมื่อแรงกดดันบริบทสูง และในระดับ Compaction ที่แนะนำ จะแสดงปุ่มกะทัดรัดที่เรียกใช้เส้นทาง Compaction เซสชันตามปกติ สแนปชอตโทเค็นที่ล้าสมัยจะถูกซ่อนไว้จนกว่า Gateway จะรายงานการใช้งานสดอีกครั้ง
    โหมดพูดคุย (เรียลไทม์ในเบราว์เซอร์)

    โหมดพูดคุยใช้ผู้ให้บริการเสียงเรียลไทม์ที่ลงทะเบียนไว้ กำหนดค่า OpenAI ด้วย talk.realtime.provider: "openai" พร้อม talk.realtime.providers.openai.apiKey หรือกำหนดค่า Google ด้วย talk.realtime.provider: "google" พร้อม talk.realtime.providers.google.apiKey เบราว์เซอร์จะไม่ได้รับคีย์ API ของผู้ให้บริการมาตรฐาน OpenAI จะได้รับความลับไคลเอนต์ Realtime ชั่วคราวสำหรับ WebRTC Google Live จะได้รับโทเค็นยืนยันตัวตน Live API แบบจำกัดที่ใช้ครั้งเดียวสำหรับเซสชัน WebSocket ในเบราว์เซอร์ โดยมีคำสั่งและการประกาศเครื่องมือที่ Gateway ล็อกไว้ในโทเค็น ผู้ให้บริการที่เปิดเผยเฉพาะบริดจ์เรียลไทม์ฝั่งแบ็กเอนด์จะทำงานผ่านทรานสปอร์ตรีเลย์ของ Gateway ดังนั้นข้อมูลประจำตัวและซ็อกเก็ตผู้ขายจะอยู่ฝั่งเซิร์ฟเวอร์ ขณะที่เสียงของเบราว์เซอร์เคลื่อนผ่าน RPC ของ Gateway ที่ผ่านการยืนยันตัวตน พรอมป์เซสชัน Realtime ถูกประกอบโดย Gateway; talk.client.create ไม่ยอมรับการโอเวอร์ไรด์คำสั่งที่ผู้เรียกให้มา

    ในตัวเขียน Chat ตัวควบคุม Talk คือปุ่มรูปคลื่นข้างปุ่มถอดเสียงจากไมโครโฟน เมื่อ Talk เริ่มต้น แถวสถานะของตัวเขียนจะแสดง Connecting Talk... จากนั้นแสดง Talk live ขณะเชื่อมต่อเสียง หรือ Asking OpenClaw... ขณะที่การเรียกเครื่องมือเรียลไทม์กำลังปรึกษาโมเดลขนาดใหญ่กว่าที่กำหนดค่าไว้ผ่าน talk.client.toolCall

    การทดสอบสดแบบ smoke สำหรับผู้ดูแล: OPENAI_API_KEY=... GEMINI_API_KEY=... node --import tsx scripts/dev/realtime-talk-live-smoke.ts ตรวจสอบการแลกเปลี่ยน SDP ของ OpenAI WebRTC ในเบราว์เซอร์, การตั้งค่า WebSocket เบราว์เซอร์ของ Google Live ด้วยโทเค็นจำกัด และอะแดปเตอร์เบราว์เซอร์รีเลย์ของ Gateway พร้อมสื่อไมโครโฟนจำลอง คำสั่งนี้พิมพ์เฉพาะสถานะผู้ให้บริการและไม่บันทึกความลับ

    หยุดและยกเลิก
    • คลิก Stop (เรียก chat.abort)
    • ขณะที่การรันทำงานอยู่ การติดตามผลปกติจะเข้าคิว คลิก Steer บนข้อความที่เข้าคิวเพื่อฉีดการติดตามผลนั้นเข้าไปในเทิร์นที่กำลังรัน
    • พิมพ์ /stop (หรือวลีขอยกเลิกแบบเดี่ยว เช่น stop, stop action, stop run, stop openclaw, please stop) เพื่อยกเลิกนอกแถบ
    • chat.abort รองรับ { sessionKey } (ไม่มี runId) เพื่อยกเลิกการรันที่ใช้งานอยู่ทั้งหมดสำหรับเซสชันนั้น
    การคงบางส่วนไว้หลังยกเลิก
    • เมื่อการรันถูกยกเลิก ข้อความผู้ช่วยบางส่วนยังสามารถแสดงใน UI ได้
    • Gateway จะคงข้อความผู้ช่วยบางส่วนที่ถูกยกเลิกไว้ในประวัติทรานสคริปต์เมื่อมีเอาต์พุตที่บัฟเฟอร์ไว้
    • รายการที่คงไว้จะรวมเมตาดาตาการยกเลิก เพื่อให้ผู้บริโภคทรานสคริปต์แยกข้อความบางส่วนจากการยกเลิกออกจากเอาต์พุตการเสร็จสิ้นตามปกติได้

    การติดตั้ง PWA และ Web Push

    Control UI มาพร้อม manifest.webmanifest และ service worker ดังนั้นเบราว์เซอร์สมัยใหม่จึงติดตั้งเป็น PWA แบบสแตนด์อโลนได้ Web Push ช่วยให้ Gateway ปลุก PWA ที่ติดตั้งแล้วด้วยการแจ้งเตือน แม้แท็บหรือหน้าต่างเบราว์เซอร์จะไม่ได้เปิดอยู่

    พื้นผิว สิ่งที่ทำ
    ui/public/manifest.webmanifest แมนิเฟสต์ PWA เบราว์เซอร์จะเสนอ "ติดตั้งแอป" เมื่อเข้าถึงได้
    ui/public/sw.js service worker ที่จัดการเหตุการณ์ push และการคลิกการแจ้งเตือน
    push/vapid-keys.json (ภายใต้ไดเรกทอรีสถานะ OpenClaw) คู่คีย์ VAPID ที่สร้างอัตโนมัติ ใช้ลงนามเพย์โหลด Web Push
    push/web-push-subscriptions.json ปลายทางการสมัครสมาชิกเบราว์เซอร์ที่คงไว้

    โอเวอร์ไรด์คู่คีย์ VAPID ผ่านตัวแปรสภาพแวดล้อมในโปรเซส Gateway เมื่อคุณต้องการตรึงคีย์ (สำหรับการปรับใช้หลายโฮสต์ การหมุนเวียนความลับ หรือการทดสอบ):

    • OPENCLAW_VAPID_PUBLIC_KEY
    • OPENCLAW_VAPID_PRIVATE_KEY
    • OPENCLAW_VAPID_SUBJECT (ค่าเริ่มต้นเป็น mailto:openclaw@localhost)

    Control UI ใช้เมธอด Gateway ที่จำกัดด้วยขอบเขตเหล่านี้เพื่อลงทะเบียนและทดสอบการสมัครสมาชิกเบราว์เซอร์:

    • push.web.vapidPublicKey — ดึงคีย์สาธารณะ VAPID ที่ใช้งานอยู่
    • push.web.subscribe — ลงทะเบียน endpoint พร้อม keys.p256dh/keys.auth
    • push.web.unsubscribe — ลบปลายทางที่ลงทะเบียนไว้
    • push.web.test — ส่งการแจ้งเตือนทดสอบไปยังการสมัครสมาชิกของผู้เรียก

    การฝังที่โฮสต์ไว้

    ข้อความผู้ช่วยสามารถเรนเดอร์เนื้อหาเว็บที่โฮสต์ไว้แบบอินไลน์ด้วยชอร์ตโค้ด [embed ...] นโยบายแซนด์บ็อกซ์ของ iframe ถูกควบคุมโดย gateway.controlUi.embedSandbox:

    เข้มงวด

    ปิดใช้การเรียกใช้สคริปต์ภายในการฝังที่โฮสต์ไว้

    สคริปต์ (ค่าเริ่มต้น)

    อนุญาตการฝังแบบโต้ตอบโดยยังคงแยก origin ไว้ นี่คือค่าเริ่มต้นและมักเพียงพอสำหรับเกม/วิดเจ็ตเบราว์เซอร์แบบครบในตัว

    เชื่อถือแล้ว

    เพิ่ม allow-same-origin บน allow-scripts สำหรับเอกสารในไซต์เดียวกันที่ตั้งใจต้องการสิทธิ์ที่แข็งแรงกว่า

    ตัวอย่าง:

    {
      gateway: {
        controlUi: {
          embedSandbox: "scripts",
        },
      },
    }
    

    URL การฝัง http(s) ภายนอกแบบสัมบูรณ์ยังคงถูกบล็อกโดยค่าเริ่มต้น หากคุณตั้งใจต้องการให้ [embed url="https://..."] โหลดหน้าของบุคคลที่สาม ให้ตั้งค่า gateway.controlUi.allowExternalEmbedUrls: true

    ความกว้างข้อความแชต

    ข้อความแชตที่จัดกลุ่มใช้ความกว้างสูงสุดเริ่มต้นที่อ่านง่าย การปรับใช้บนจอกว้างสามารถโอเวอร์ไรด์ได้โดยไม่ต้องแพตช์ CSS ที่บันเดิลมา ด้วยการตั้งค่า gateway.controlUi.chatMessageMaxWidth:

    {
      gateway: {
        controlUi: {
          chatMessageMaxWidth: "min(1280px, 82%)",
        },
      },
    }
    

    ค่าจะถูกตรวจสอบก่อนถึงเบราว์เซอร์ ค่าที่รองรับรวมถึงความยาวธรรมดาและเปอร์เซ็นต์ เช่น 960px หรือ 82% รวมถึงนิพจน์ความกว้างแบบจำกัด min(...), max(...), clamp(...), calc(...) และ fit-content(...)

    การเข้าถึง tailnet (แนะนำ)

    Tailscale Serve แบบรวมในตัว (แนะนำ)

    ให้ Gateway อยู่บน loopback และให้ Tailscale Serve พร็อกซีด้วย HTTPS:

    openclaw gateway --tailscale serve
    

    เปิด:

    • https://<magicdns>/ (หรือ gateway.controlUi.basePath ที่คุณกำหนดค่าไว้)

    โดยค่าเริ่มต้น คำขอ Control UI/WebSocket Serve สามารถยืนยันตัวตนผ่านส่วนหัวตัวตนของ Tailscale (tailscale-user-login) เมื่อ gateway.auth.allowTailscale เป็น true OpenClaw ตรวจสอบตัวตนโดยแก้ที่อยู่ x-forwarded-for ด้วย tailscale whois และจับคู่กับส่วนหัว และจะยอมรับเฉพาะเมื่อคำขอเข้ามาที่ loopback พร้อมส่วนหัว x-forwarded-* ของ Tailscale สำหรับเซสชันผู้ปฏิบัติงาน Control UI ที่มีตัวตนอุปกรณ์เบราว์เซอร์ เส้นทาง Serve ที่ตรวจสอบแล้วนี้จะข้ามรอบการจับคู่อุปกรณ์ด้วย เบราว์เซอร์ที่ไม่มีอุปกรณ์และการเชื่อมต่อบทบาทโหนดยังคงทำตามการตรวจสอบอุปกรณ์ปกติ ตั้งค่า gateway.auth.allowTailscale: false หากคุณต้องการบังคับใช้ข้อมูลประจำตัว shared-secret อย่างชัดเจนแม้สำหรับทราฟฟิก Serve จากนั้นใช้ gateway.auth.mode: "token" หรือ "password"

    สำหรับเส้นทางตัวตน Serve แบบ async นั้น ความพยายามยืนยันตัวตนที่ล้มเหลวสำหรับ IP ไคลเอนต์และขอบเขตการยืนยันตัวตนเดียวกันจะถูกทำให้เป็นลำดับก่อนเขียน rate-limit ดังนั้นการลองซ้ำที่ผิดพลาดพร้อมกันจากเบราว์เซอร์เดียวกันอาจแสดง retry later ในคำขอที่สอง แทนที่จะเป็นความไม่ตรงกันแบบธรรมดาสองรายการที่แข่งกันแบบขนาน

    ผูกกับ tailnet + โทเค็น

    openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)"
    

    จากนั้นเปิด:

    • http://<tailscale-ip>:18789/ (หรือ gateway.controlUi.basePath ที่คุณกำหนดค่าไว้)

    วางความลับร่วมที่ตรงกันลงในการตั้งค่าอินเทอร์เฟซ (ส่งเป็น connect.params.auth.token หรือ connect.params.auth.password).

    HTTP ที่ไม่ปลอดภัย

    หากคุณเปิดแดชบอร์ดผ่าน HTTP แบบธรรมดา (http://<lan-ip> หรือ http://<tailscale-ip>), เบราว์เซอร์จะทำงานใน บริบทที่ไม่ปลอดภัย และบล็อก WebCrypto โดยค่าเริ่มต้น OpenClaw บล็อก การเชื่อมต่ออินเทอร์เฟซควบคุมที่ไม่มีข้อมูลระบุตัวตนของอุปกรณ์

    ข้อยกเว้นที่บันทึกไว้:

    • ความเข้ากันได้กับ HTTP ที่ไม่ปลอดภัยเฉพาะ localhost ด้วย gateway.controlUi.allowInsecureAuth=true
    • การยืนยันตัวตนอินเทอร์เฟซควบคุมของผู้ปฏิบัติการสำเร็จผ่าน gateway.auth.mode: "trusted-proxy"
    • ตัวเลือกฉุกเฉิน gateway.controlUi.dangerouslyDisableDeviceAuth=true

    วิธีแก้ไขที่แนะนำ: ใช้ HTTPS (Tailscale Serve) หรือเปิดอินเทอร์เฟซในเครื่อง:

    • https://<magicdns>/ (Serve)
    • http://127.0.0.1:18789/ (บนโฮสต์ Gateway)
    พฤติกรรมของตัวสลับการยืนยันตัวตนที่ไม่ปลอดภัย
    {
      gateway: {
        controlUi: { allowInsecureAuth: true },
        bind: "tailnet",
        auth: { mode: "token", token: "replace-me" },
      },
    }
    

    allowInsecureAuth เป็นตัวสลับความเข้ากันได้ในเครื่องเท่านั้น:

    • อนุญาตให้เซสชันอินเทอร์เฟซควบคุมบน localhost ดำเนินต่อได้โดยไม่มีข้อมูลระบุตัวตนของอุปกรณ์ในบริบท HTTP ที่ไม่ปลอดภัย
    • ไม่ข้ามการตรวจสอบการจับคู่
    • ไม่ผ่อนคลายข้อกำหนดข้อมูลระบุตัวตนของอุปกรณ์ระยะไกล (ที่ไม่ใช่ localhost)
    สำหรับกรณีฉุกเฉินเท่านั้น
    {
      gateway: {
        controlUi: { dangerouslyDisableDeviceAuth: true },
        bind: "tailnet",
        auth: { mode: "token", token: "replace-me" },
      },
    }
    
    หมายเหตุเกี่ยวกับพร็อกซีที่เชื่อถือได้
    • การยืนยันตัวตนแบบ trusted-proxy ที่สำเร็จสามารถอนุญาตเซสชันอินเทอร์เฟซควบคุมของ ผู้ปฏิบัติการ โดยไม่มีข้อมูลระบุตัวตนอุปกรณ์ได้
    • สิ่งนี้ ไม่ ครอบคลุมถึงเซสชันอินเทอร์เฟซควบคุมสำหรับบทบาท Node
    • พร็อกซีย้อนกลับแบบลูปแบ็กบนโฮสต์เดียวกันยังไม่เข้าเงื่อนไขการยืนยันตัวตนแบบ trusted-proxy; ดู การยืนยันตัวตนพร็อกซีที่เชื่อถือได้

    ดู Tailscale สำหรับคำแนะนำในการตั้งค่า HTTPS

    นโยบายความปลอดภัยของเนื้อหา

    อินเทอร์เฟซควบคุมมาพร้อมกับนโยบาย img-src ที่เข้มงวด: อนุญาตเฉพาะแอสเซ็ต ต้นทางเดียวกัน, URL data: และ URL blob: ที่สร้างขึ้นในเครื่องเท่านั้น URL รูปภาพระยะไกลแบบ http(s) และแบบสัมพันธ์กับโปรโตคอลจะถูกเบราว์เซอร์ปฏิเสธและจะไม่ส่งคำขอดึงข้อมูลเครือข่าย

    ในทางปฏิบัติหมายความว่า:

    • อวาตาร์และรูปภาพที่ให้บริการภายใต้พาธแบบสัมพันธ์ (เช่น /avatars/<id>) ยังคงแสดงผลได้ รวมถึงเส้นทางอวาตาร์ที่ต้องยืนยันตัวตนซึ่งอินเทอร์เฟซดึงข้อมูลและแปลงเป็น URL blob: ในเครื่อง
    • URL แบบอินไลน์ data:image/... ยังคงแสดงผลได้ (มีประโยชน์สำหรับเพย์โหลดภายในโปรโตคอล)
    • URL blob: ในเครื่องที่สร้างโดยอินเทอร์เฟซควบคุมยังคงแสดงผลได้
    • URL อวาตาร์ระยะไกลที่ปล่อยออกมาจากเมทาดาทาของช่องจะถูกตัดออกที่ตัวช่วยอวาตาร์ของอินเทอร์เฟซควบคุมและแทนที่ด้วยโลโก้/แบดจ์ในตัว ดังนั้นช่องที่ถูกบุกรุกหรือเป็นอันตรายจึงไม่สามารถบังคับให้เบราว์เซอร์ของผู้ปฏิบัติการดึงรูปภาพระยะไกลใดๆ ได้

    คุณไม่จำเป็นต้องเปลี่ยนอะไรเพื่อให้ได้พฤติกรรมนี้ — พฤติกรรมนี้เปิดใช้งานเสมอและกำหนดค่าไม่ได้

    การยืนยันตัวตนของเส้นทางอวาตาร์

    เมื่อกำหนดค่าการยืนยันตัวตนของ Gateway แล้ว ปลายทางอวาตาร์ของอินเทอร์เฟซควบคุมต้องใช้โทเค็น Gateway เดียวกันกับ API ส่วนที่เหลือ:

    • GET /avatar/<agentId> ส่งคืนรูปภาพอวาตาร์ให้เฉพาะผู้เรียกที่ยืนยันตัวตนแล้วเท่านั้น GET /avatar/<agentId>?meta=1 ส่งคืนเมทาดาทาอวาตาร์ภายใต้กฎเดียวกัน
    • คำขอที่ไม่ได้ยืนยันตัวตนไปยังเส้นทางใดเส้นทางหนึ่งจะถูกปฏิเสธ (ตรงกับเส้นทางสื่อผู้ช่วยที่เป็นพี่น้องกัน) สิ่งนี้ป้องกันไม่ให้เส้นทางอวาตาร์รั่วไหลข้อมูลระบุตัวตนของเอเจนต์บนโฮสต์ที่มีการป้องกันอยู่แล้ว
    • อินเทอร์เฟซควบคุมจะส่งต่อโทเค็น Gateway เป็นส่วนหัว bearer เมื่อดึงอวาตาร์ และใช้ URL blob ที่ยืนยันตัวตนแล้วเพื่อให้รูปภาพยังคงแสดงผลในแดชบอร์ด

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

    การยืนยันตัวตนของเส้นทางสื่อผู้ช่วย

    เมื่อกำหนดค่าการยืนยันตัวตนของ Gateway แล้ว ตัวอย่างสื่อในเครื่องของผู้ช่วยจะใช้เส้นทางสองขั้นตอน:

    • GET /__openclaw__/assistant-media?meta=1&source=<path> ต้องใช้การยืนยันตัวตนของผู้ปฏิบัติการอินเทอร์เฟซควบคุมตามปกติ เบราว์เซอร์จะส่งโทเค็น Gateway เป็นส่วนหัว bearer เมื่อตรวจสอบความพร้อมใช้งาน
    • การตอบกลับเมทาดาทาที่สำเร็จจะมี mediaTicket อายุสั้นที่จำกัดขอบเขตไว้กับพาธต้นทางนั้นโดยตรง
    • URL รูปภาพ เสียง วิดีโอ และเอกสารที่เบราว์เซอร์แสดงผลใช้ mediaTicket=<ticket> แทนโทเค็นหรือรหัสผ่าน Gateway ที่ใช้งานอยู่ ตั๋วจะหมดอายุอย่างรวดเร็วและไม่สามารถอนุญาตต้นทางอื่นได้

    สิ่งนี้ทำให้การแสดงผลสื่อปกติเข้ากันได้กับองค์ประกอบสื่อเนทีฟของเบราว์เซอร์ โดยไม่ใส่ข้อมูลประจำตัว Gateway ที่นำกลับมาใช้ซ้ำได้ไว้ใน URL สื่อที่มองเห็นได้

    การสร้างอินเทอร์เฟซ

    Gateway ให้บริการไฟล์สแตติกจาก dist/control-ui สร้างไฟล์เหล่านั้นด้วย:

    pnpm ui:build
    

    ฐานแบบสัมบูรณ์ที่เลือกได้ (เมื่อคุณต้องการ URL แอสเซ็ตแบบตายตัว):

    OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build
    

    สำหรับการพัฒนาในเครื่อง (เซิร์ฟเวอร์พัฒนาแยกต่างหาก):

    pnpm ui:dev
    

    จากนั้นชี้อินเทอร์เฟซไปที่ URL WS ของ Gateway ของคุณ (เช่น ws://127.0.0.1:18789).

    การดีบัก/ทดสอบ: เซิร์ฟเวอร์พัฒนา + Gateway ระยะไกล

    อินเทอร์เฟซควบคุมเป็นไฟล์สแตติก; เป้าหมาย WebSocket กำหนดค่าได้และอาจแตกต่างจากต้นทาง HTTP ได้ สิ่งนี้สะดวกเมื่อคุณต้องการเซิร์ฟเวอร์พัฒนา Vite ในเครื่อง แต่ Gateway ทำงานอยู่ที่อื่น

  • เริ่มเซิร์ฟเวอร์พัฒนาอินเทอร์เฟซ

    pnpm ui:dev
    
  • เปิดด้วย gatewayUrl

    http://localhost:5173/?gatewayUrl=ws%3A%2F%2F<gateway-host>%3A18789
    

    การยืนยันตัวตนครั้งเดียวที่เลือกได้ (หากจำเป็น):

    http://localhost:5173/?gatewayUrl=wss%3A%2F%2F<gateway-host>%3A18789#token=<gateway-token>
    
  • หมายเหตุ
    • gatewayUrl จะถูกเก็บไว้ใน localStorage หลังโหลดและถูกนำออกจาก URL
    • หากคุณส่งปลายทาง ws:// หรือ wss:// แบบเต็มผ่าน gatewayUrl ให้เข้ารหัสค่า gatewayUrl สำหรับ URL เพื่อให้เบราว์เซอร์แยกวิเคราะห์สตริงคำขอได้อย่างถูกต้อง
    • ควรส่ง token ผ่านส่วน fragment ของ URL (#token=...) เมื่อเป็นไปได้ Fragment จะไม่ถูกส่งไปยังเซิร์ฟเวอร์ ซึ่งหลีกเลี่ยงการรั่วไหลในบันทึกคำขอและ Referer พารามิเตอร์คำขอแบบเดิม ?token= ยังคงถูกนำเข้าเพียงครั้งเดียวเพื่อความเข้ากันได้ แต่เป็นเพียงทางสำรองเท่านั้น และจะถูกตัดออกทันทีหลัง bootstrap
    • password จะเก็บไว้ในหน่วยความจำเท่านั้น
    • เมื่อกำหนด gatewayUrl แล้ว อินเทอร์เฟซจะไม่ถอยกลับไปใช้ข้อมูลประจำตัวจากการกำหนดค่าหรือสภาพแวดล้อม ระบุ token (หรือ password) อย่างชัดเจน การไม่มีข้อมูลประจำตัวที่ระบุอย่างชัดเจนถือเป็นข้อผิดพลาด
    • ใช้ wss:// เมื่อ Gateway อยู่หลัง TLS (Tailscale Serve, พร็อกซี HTTPS ฯลฯ)
    • gatewayUrl จะยอมรับเฉพาะในหน้าต่างระดับบนสุด (ไม่ใช่แบบฝัง) เพื่อป้องกัน clickjacking
    • การปรับใช้インเทอร์เฟซควบคุมที่ไม่ใช่ลูปแบ็กต้องกำหนด gateway.controlUi.allowedOrigins อย่างชัดเจน (ต้นทางแบบเต็ม) ซึ่งรวมถึงการตั้งค่าพัฒนาแบบระยะไกล
    • การเริ่มต้น Gateway อาจเติมต้นทางในเครื่อง เช่น http://localhost:<port> และ http://127.0.0.1:<port> จาก bind และพอร์ตขณะรันไทม์ที่มีผล แต่ต้นทางของเบราว์เซอร์ระยะไกลยังคงต้องมีรายการที่ระบุอย่างชัดเจน
    • อย่าใช้ gateway.controlUi.allowedOrigins: ["*"] ยกเว้นสำหรับการทดสอบในเครื่องที่ควบคุมอย่างเข้มงวด หมายถึงอนุญาตทุกต้นทางของเบราว์เซอร์ ไม่ใช่ "จับคู่โฮสต์ใดก็ตามที่ฉันกำลังใช้"
    • gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true เปิดใช้งานโหมดถอยกลับต้นทางจากส่วนหัว Host แต่เป็นโหมดความปลอดภัยที่อันตราย

    ตัวอย่าง:

    {
      gateway: {
        controlUi: {
          allowedOrigins: ["http://localhost:5173"],
        },
      },
    }
    

    รายละเอียดการตั้งค่าการเข้าถึงระยะไกล: การเข้าถึงระยะไกล.

    ที่เกี่ยวข้อง