การเขียนสคริปต์ JavaScript

Chute รองรับการเขียนสคริปต์ JavaScript สำหรับการแก้ไขคำขอ/การตอบกลับขั้นสูง การจับคู่กฎที่กำหนดเอง การแก้ไข DNS และงานตามกำหนดเวลา สคริปต์ใช้เอนจิน JavaScriptCore ของ Apple และทำตาม API สคริปต์ที่เข้ากันได้กับ Surge

สคริปต์ถูกกำหนดในส่วน [Script] ของไฟล์การกำหนดค่า

การกำหนดค่า

[Script]
MyScript = type=http-request, script-path=/path/to/script.js, pattern=^https?://example\.com, requires-body=true, max-size=262144, timeout=10, argument=myArg
CronJob = type=cron, script-path=/path/to/cron.js, cron-expression=*/30 * * * *

พารามิเตอร์สคริปต์

พารามิเตอร์ จำเป็น ค่าเริ่มต้น คำอธิบาย
type ใช่ http-request ประเภททริกเกอร์สคริปต์ (ดูด้านล่าง)
script-path ใช่ เส้นทางไฟล์ในเครื่องหรือ URL HTTP(S) ไปยังสคริปต์ JS
pattern ไม่ (ตรงทั้งหมด) รูปแบบ regex URL เพื่อกรองเมื่อสคริปต์ทริกเกอร์
requires-body ไม่ ตรวจจับอัตโนมัติ บังคับให้สคริปต์รับเนื้อหาคำขอ/การตอบกลับเต็มรูปแบบ
max-size ไม่ 131072 (128KB) ขนาดเนื้อหาสูงสุดเป็นไบต์สำหรับสคริปต์ที่เข้าถึงเนื้อหา หากเนื้อหาที่รวบรวมมีขนาดเกินนี้ สคริปต์จะถูกข้ามสำหรับคำขอนั้น (เนื้อหาจะไม่ถูกตัดทอน)
timeout ไม่ 5.0 วินาที เวลาหมดการทำงานต่อสคริปต์ ค่าที่เกิน 30 วินาทีจะถูกจำกัดไว้ที่ 30
argument ไม่ อาร์กิวเมนต์สตริงที่กำหนดเอง พร้อมใช้งานเป็น $argument ใน JS
debug ไม่ false สงวนไว้; ปัจจุบันไม่มีผล
cron-expression ไม่ นิพจน์กำหนดเวลา cron (สำหรับประเภท cron เท่านั้น)
wake-system ไม่ false สงวนไว้; ถูกวิเคราะห์แต่ปัจจุบันไม่มีผล
enable ไม่ true เปิดหรือปิดใช้งานสคริปต์นี้
script-update-interval ไม่ 0 การสำรวจการอัปเดตสคริปต์ระยะไกล (ดูโมเดลการทำงาน)

ประเภทสคริปต์

สตริงประเภท Enum คำอธิบาย
http-request HTTP Request ดักจับและแก้ไขคำขอ HTTP ก่อนอัปสตรีม
http-response HTTP Response ดักจับและแก้ไขการตอบกลับ HTTP ก่อนไคลเอนต์
http-request-before-send HTTP Request Before Send แก้ไขคำขอหลังจากรวบรวมเนื้อหาเต็ม ก่อนส่ง
rule Rule ตรรกะการจับคู่กฎที่กำหนดเอง
dns DNS การแก้ไข DNS ที่กำหนดเอง
cron Cron สคริปต์ตามกำหนดเวลา
event Event ตัวจัดการเหตุการณ์ระบบ (เช่น network-changed)

การตรวจจับเนื้อหาอัตโนมัติ: หากซอร์สสคริปต์มี $request.body หรือ $response.body เนื้อหาจะถูกให้โดยอัตโนมัติสูงสุด max-size ใช้ requires-body=true เพื่อบังคับพฤติกรรมนี้


การอ้างอิง API JavaScript

สคริปต์ทำงานในสภาพแวดล้อม JavaScriptCore แบบแซนด์บ็อกซ์พร้อมวัตถุส่วนกลางต่อไปนี้

$request (อ่านอย่างเดียว)

พร้อมใช้งานใน: http-request, http-response, http-request-before-send, rule

คุณสมบัติ ประเภท คำอธิบาย
.url String URL คำขอแบบเต็ม
.method String เมธอด HTTP (GET, POST ฯลฯ) หรือ QUERY สำหรับ DNS
.headers Object ส่วนหัวคำขอเป็นคู่ key-value
.body String หรือ null เนื้อหาคำขอ (ถอดรหัส UTF-8)
.bodyBytes Uint8Array หรือ null ไบต์ดิบของเนื้อหาคำขอ
.hostname String ชื่อโฮสต์เป้าหมาย
.destPort Number พอร์ตปลายทาง
.processPath String เส้นทางกระบวนการที่ร้องขอ (เฉพาะ macOS)
.userAgent String ค่าส่วนหัว User-Agent
.sourceIP String ที่อยู่ IP ต้นทาง
.listenPort Number พอร์ตการฟังของพร็อกซี
.requestId String ID คำขอที่ไม่ซ้ำ
.dnsResult String ที่อยู่ IP ที่แก้ไขแล้ว
.srcPort Number พอร์ตต้นทาง
.protocol String โปรโตคอลที่ตรวจพบ: http, https, tcp, dns

$response (อ่านอย่างเดียว)

พร้อมใช้งานใน: http-response

คุณสมบัติ ประเภท คำอธิบาย
.status Number รหัสสถานะ HTTP
.headers Object ส่วนหัวการตอบกลับเป็นคู่ key-value
.body String หรือ null เนื้อหาการตอบกลับ (ถอดรหัส UTF-8)
.bodyBytes Uint8Array หรือ null ไบต์ดิบของเนื้อหาการตอบกลับ
.rawBody Uint8Array หรือ null ชื่อพ้องของ .bodyBytes

$done(value) — ตัวจัดการการเสร็จสมบูรณ์

ต้องถูกเรียกหนึ่งครั้งอย่างแน่นอนเมื่อสิ้นสุดสคริปต์เพื่อส่งสัญญาณการเสร็จสมบูรณ์ การทำงานของสคริปต์บล็อกจนกว่า $done() จะถูกเรียกหรือหมดเวลา

$done({})                        // ส่งผ่าน — ไม่มีการแก้ไข
$done()                          // ยกเลิกการเชื่อมต่อ
$done({matched: true})           // ผลการจับคู่กฎ (เฉพาะสคริปต์กฎ)
$done({address: "1.2.3.4"})      // ผลลัพธ์ DNS (เฉพาะสคริปต์ dns)

ค่าส่งคืนของสคริปต์ HTTP Request:

$done({
    url: "https://new.example.com/path",     // เขียน URL ใหม่
    headers: {"X-Custom": "value"},           // แก้ไขส่วนหัว
    body: "new request body",                 // แก้ไขเนื้อหา
    response: {                               // ส่งคืนการตอบกลับสังเคราะห์ (ข้ามอัปสตรีม)
        status: 200,
        headers: {"Content-Type": "text/html"},
        body: "<html>Blocked</html>"
    }
})

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

ค่าส่งคืนของสคริปต์ HTTP Response:

$done({
    status: 200,                              // แก้ไขรหัสสถานะ
    headers: {"X-Custom": "value"},           // แก้ไขส่วนหัวการตอบกลับ
    body: "new response body",                // แก้ไขเนื้อหาการตอบกลับ
    url: "https://other.example.com"          // ทริกเกอร์การเปลี่ยนเส้นทาง 302
})

เมื่อระบุ url Chute ส่งคืนการเปลี่ยนเส้นทาง 302 ไปยัง URL ที่กำหนดแทนการตอบกลับเดิม url ต้องถูกส่งคืนร่วมกับอย่างน้อยหนึ่งใน status / headers / body; ผลลัพธ์ที่มีเพียง url เท่านั้นจะถูกปฏิบัติเป็นการส่งผ่าน

ค่าส่งคืนของสคริปต์ DNS:

$done({address: "1.2.3.4"})                  // IP เดียว
$done({addresses: ["1.2.3.4", "5.6.7.8"]})   // หลาย IP
$done({address: "10.0.0.1", ttl: 300})       // พร้อม TTL ที่กำหนดเอง (วินาที, ค่าเริ่มต้น 60)

คีย์ server / servers จะถูกยอมรับแต่ปัจจุบันถูกละเว้น; การแก้ไขจะตกไปยัง DNS ปกติ

$httpClient — ไคลเอนต์ HTTP แบบ Async

ทำคำขอ HTTP จากภายในสคริปต์ คำขอทั้งหมดถูกยกเลิกเมื่อ $done() หรือหมดเวลา

$httpClient.get(url, function(error, response, data) {
    if (error) {
        console.log("Request failed: " + error)
    } else {
        console.log("Status: " + response.status)
        console.log("Response: " + data)
    }
})

$httpClient.post(url, {headers: {...}, body: "...", timeout: 5}, callback)
$httpClient.put(url, options, callback)
$httpClient.del(url, options, callback)
$httpClient.head(url, options, callback)
$httpClient.options(url, options, callback)
$httpClient.patch(url, options, callback)

ลายเซ็น Callback: callback(error, response, data)

  • error: สตริงข้อผิดพลาดหรือ null
  • response: {status: Number, headers: Object} หรือ null
  • data: สตริงเนื้อหาการตอบกลับ UTF-8 หรือ null

$httpClient พร้อมใช้งานในสคริปต์ http-request, http-response, http-request-before-send, cron และ event แต่ไม่พร้อมใช้งานในสคริปต์ rule และ dns

$persistentStore — ที่เก็บคีย์-ค่า

ที่เก็บคีย์-ค่าแบบถาวรที่คงอยู่ข้ามการเริ่มต้นสคริปต์และกระบวนการ สนับสนุนโดย NSUserDefaults

$persistentStore.write(data, key)   // เก็บค่า
$persistentStore.read(key)          // ดึงค่า
$persistentStore.remove(key)        // ลบค่า

$notification — การแจ้งเตือนในเครื่อง

ส่งการแจ้งเตือนระบบในเครื่อง

$notification.post("Title", "Subtitle", "Notification body text")

$network — ข้อมูลเครือข่าย

ข้อมูลสถานะเครือข่ายแบบอ่านอย่างเดียว

$network.dns   // อาร์เรย์ของ IP เซิร์ฟเวอร์ DNS
$network.wifi  // {ssid: "WiFiName", bssid: null}

bssid จะเป็น null เสมอ; ssid จะมีค่าเฉพาะบน iOS เท่านั้น

ข้อสังเกต: ในรุ่นปัจจุบัน คุณสมบัติ $network และ $environment ไม่สามารถมองเห็นได้จากสคริปต์เนื่องจากข้อจำกัดของการเชื่อมโยง (bridging) และจะอ่านได้เป็น undefined ข้อมูลเมตา $script มีให้เฉพาะในสคริปต์ cron และ event เท่านั้น

$environment — ข้อมูลรันไทม์

$environment.system     // "iOS" หรือ "macOS"
$environment.appVersion // สตริงเวอร์ชัน KLNEKit SDK

$utils — ยูทิลิตี้

$utils.geoip("1.2.3.4")   // รหัสประเทศ (เช่น "US")
$utils.ipasn("1.2.3.4")   // หมายเลข ASN (เช่น "13335")
$utils.ungzip(data)       // คลายการบีบอัดข้อมูล gzip

$klne — API ควบคุมพร็อกซี

ควบคุมรันไทม์พร็อกซีจากสคริปต์ $klne พร้อมใช้งานในสคริปต์ทุกประเภท

$klne.getPolicyGroups()               // รับกลุ่มนโยบายทั้งหมด
$klne.selectPolicy("Group", "Proxy")  // สลับนโยบายสำหรับกลุ่ม
$klne.getActiveConnections()          // แสดงรายการการเชื่อมต่อที่ใช้งาน
$klne.closeConnection("id")           // สงวนไว้ — ปัจจุบันไม่ทำอะไร
$klne.flushDNS()                      // ล้างแคช DNS
$klne.startURLTest("Group")           // ทริกเกอร์การทดสอบ URL สำหรับกลุ่ม
$klne.reloadConfiguration()           // โหลดการกำหนดค่าทั้งหมดใหม่
$klne.setOutboundMode("rule")         // ตั้งค่าโหมด: "global"/"proxy", "direct", "rule"
$klne.setHTTPCaptureEnabled(true)     // เปิด/ปิด MitM

getPolicyGroups() ส่งคืนกลุ่มนโยบายที่เลือกได้:

{
  count: 1,                    // Number — จำนวนกลุ่ม
  policyGroups: [{
    name: "MainGroup",         // String — ชื่อกลุ่ม
    type: 0,                   // Number — 0 select, 1 url-test, 2 fallback, 3 ssid, 5 load-balance
    policyNames: ["A", "B"],   // Array of String — นโยบายตัวเลือก
    selectedIndex: 0,          // Number — ดัชนีของนโยบายที่ใช้งานอยู่ (ไม่มีเมื่อยังระบุไม่ได้)
    selectedPolicy: "A"        // String — ชื่อของนโยบายที่ใช้งานอยู่ (ไม่มีเมื่อยังระบุไม่ได้)
  }]
}

getActiveConnections() ส่งคืน Array ที่อธิบายการเชื่อมต่อปัจจุบัน:

[{
  id: "0x600002f01230",  // String — ตัวระบุการเชื่อมต่อแบบทึบ
  host: "example.com",   // String — โฮสต์ปลายทาง (ไม่มีเมื่อไม่ทราบ)
  port: 443              // Number — พอร์ตปลายทาง
}]

เมธอดที่เหลือรับอาร์กิวเมนต์ธรรมดาและไม่ส่งคืนค่าใด ๆ:

  • selectPolicy(group, policy) — ทำให้ policy (ชื่อจาก policyNames ของกลุ่มนั้น) เป็นนโยบายที่ใช้งานอยู่ของ group ชื่อกลุ่มหรือนโยบายที่ไม่รู้จักจะถูกเพิกเฉยพร้อมคำเตือนในบันทึก
  • closeConnection(id) — สงวนไว้ เคอร์เนลปัจจุบันไม่สามารถปิดการเชื่อมต่อรายตัวได้; การเรียกใช้จะเพียงบันทึกคำเตือนและไม่ปิดอะไรเลย
  • flushDNS() — ล้างแคช DNS
  • startURLTest(group) — เริ่มการทดสอบเวลาแฝงแบบอะซิงโครนัสสำหรับกลุ่มประเภท url-test หรือ fallback; ประเภทกลุ่มอื่นและชื่อที่ไม่รู้จักจะถูกเพิกเฉยพร้อมคำเตือน
  • reloadConfiguration() — โหลดการกำหนดค่าปัจจุบันใหม่
  • setOutboundMode(mode) — ทั้ง "global" และ "proxy" ส่งทราฟฟิกทั้งหมดผ่านพร็อกซี, "direct" ส่งทราฟฟิกทั้งหมดแบบตรง และค่าอื่นใดจะเลือกโหมดตามกฎ
  • setHTTPCaptureEnabled(enabled) — เปิดหรือปิดการถอดรหัส HTTPS (MitM) ที่รันไทม์; รับค่าบูลีน

$script — ข้อมูลเมตาสคริปต์

$script.name       // ชื่อสคริปต์จากการกำหนดค่า
$script.type       // สตริงประเภทสคริปต์
$script.startTime  // การประทับเวลาแบบโมโนโทนิก (วินาทีนับจากจุดอ้างอิงการบูตระบบ ไม่ใช่ Epoch)

ตัวแปรส่วนกลางต่อการทำงาน

ตัวแปรต่อไปนี้ถูกฉีดต่อการทำงานของสคริปต์และเฉพาะเจาะจงกับประเภทสคริปต์บางประเภท

$argument — อาร์กิวเมนต์สคริปต์

ค่าสตริงจากพารามิเตอร์ argument= ในการกำหนดค่าสคริปต์ พร้อมใช้งานใน: http-request, http-response, http-request-before-send, rule, dns, cron, event

console.log("Argument: " + $argument)

$domain — โดเมน DNS (เฉพาะสคริปต์ DNS)

ชื่อโดเมนที่กำลังถูกสอบถาม พร้อมใช้งานเฉพาะในสคริปต์ dns

var domain = $domain  // เช่น "example.com"

$cronexp — นิพจน์ Cron (เฉพาะสคริปต์ Cron)

นิพจน์กำหนดเวลา cron จากการกำหนดค่าสคริปต์ พร้อมใช้งานเฉพาะในสคริปต์ cron

console.log("Schedule: " + $cronexp)  // เช่น "*/30 * * * *"

$event — ข้อมูลเหตุการณ์ (เฉพาะสคริปต์ Event)

ข้อมูลเกี่ยวกับเหตุการณ์ที่ทริกเกอร์ ปัจจุบันรองรับเฉพาะ network-changed

console.log("Event: " + $event.name)  // "network-changed"

console — การบันทึก

console.log("Debug message")    // บันทึกละเอียด
console.warn("Warning message")  // บันทึกคำเตือน
console.error("Error message")   // บันทึกคำเตือนที่ถูกแท็กเป็นข้อผิดพลาด JavaScript

setTimeout(fn, seconds) — ตัวจับเวลา

กำหนดเวลาฟังก์ชันให้ทำงานหลังจากดีเลย์

setTimeout(function() {
    console.log("Delayed execution")
}, 2.5)  // 2.5 วินาที

$scriptImport(subScriptPath) — ตัวโหลดสคริปต์ย่อย

โหลดและประเมินไฟล์ JavaScript อื่น รองรับเฉพาะเส้นทางไฟล์ในเครื่องเท่านั้น; URL http(s):// และ file:// จะถูกปฏิเสธ ($script ถูกสงวนไว้สำหรับวัตถุข้อมูลเมตาสคริปต์)

$scriptImport("/path/to/helper.js")

// ส่งข้อมูลระหว่างสคริปต์โดยใช้ $persistentStore

รายละเอียดประเภทสคริปต์

สคริปต์ HTTP Request

ทำงานเมื่อได้รับส่วนหัวคำขอ สามารถแก้ไข URL ส่วนหัว และเนื้อหาก่อนที่คำขอจะถูกส่งต่อ

[Script]
ModifyHeaders = type=http-request, script-path=modify.js, pattern=^https://api\.example\.com

สคริปต์ HTTP Response

ทำงานเมื่อได้รับส่วนหัวการตอบกลับ สามารถแก้ไขสถานะ ส่วนหัว และเนื้อหาก่อนส่งคืนไปยังไคลเอนต์

[Script]
ModifyResponse = type=http-response, script-path=response.js, pattern=^https://api\.example\.com

สคริปต์ HTTP Request Before Send

ทำงานหลังจากรวบรวมเนื้อหาคำขอเต็มรูปแบบ ก่อนส่งไปยังอัปสตรีม มีประโยชน์สำหรับการแก้ไขเนื้อหาคำขอ POST/PUT

[Script]
BeforeSend = type=http-request-before-send, script-path=before-send.js, pattern=^https://api\.example\.com, requires-body=true

สคริปต์ Rule

การจับคู่กฎที่กำหนดเอง สคริปต์ต้องเรียก $done({matched: true}) หรือ $done({matched: false})

[Rule]
SCRIPT,MyRuleScript,DIRECT

[Script]
MyRuleScript = type=rule, script-path=rule.js

สคริปต์ DNS

การแก้ไข DNS ที่กำหนดเอง รับ $domain และส่งคืนที่อยู่ที่แก้ไขแล้ว

// dns.js
var domain = $domain
if (domain === "internal.example.com") {
    $done({address: "10.0.0.1", ttl: 300})
} else {
    $done({})  // ส่งผ่านไปยังการแก้ไข DNS ปกติ
}

สคริปต์ Cron

การทำงานตามกำหนดเวลาโดยใช้นิพจน์ cron ช่วงขั้นต่ำคือ 60 วินาที

[Script]
HalfHourlyTask = type=cron, script-path=task.js, cron-expression=*/30 * * * *

เฉพาะฟิลด์นาทีของนิพจน์เท่านั้นที่ถูกนำมาใช้: */N ทำงานทุก N นาที นิพจน์อื่นใดจะยิงทุก 60 วินาที และสคริปต์ต้องตรวจสอบเวลาปัจจุบันด้วยตัวเองเพื่อตัดสินใจว่าจะดำเนินการหรือไม่

สคริปต์ Event

ถูกทริกเกอร์โดยเหตุการณ์ระบบ ปัจจุบันรองรับเหตุการณ์ network-changed (ยิงเมื่อ Wi-Fi หรือเครือข่ายเซลลูลาร์เปลี่ยน)

[Script]
NetChange = type=event, script-path=network-changed.js

วัตถุ $event พร้อมใช้งาน:

$event.name  // "network-changed"

ตัวอย่างการใช้งานจริง

เปลี่ยนเส้นทางอุปกรณ์มือถือ

สคริปต์ http-request ที่เปลี่ยนเส้นทางผู้ใช้มือถือตาม User-Agent:

[Script]
MobileRedirect = type=http-request, script-path=mobile-redirect.js, pattern=^https://example\.com
// mobile-redirect.js
var ua = $request.headers["User-Agent"] || ""
if (/Mobile|Android|iPhone/.test(ua)) {
    $done({
        response: {
            status: 302,
            headers: {"Location": "https://m.example.com" + $request.url.replace(/.*example\.com/, "")},
            body: ""
        }
    })
} else {
    $done({})
}

บล็อกเนื้อหาในการตอบกลับ API

สคริปต์ http-response ที่ลบโฆษณาและเนื้อหาสปอนเซอร์จากการตอบกลับ JSON API:

[Script]
RemoveAds = type=http-response, script-path=remove-ads.js, pattern=^https://api\.example\.com/feed, requires-body=true
// remove-ads.js
var body = JSON.parse($response.body)
if (body.ads) {
    delete body.ads
}
if (body.recommendations) {
    body.recommendations = body.recommendations.filter(function(r) {
        return !r.sponsored
    })
}
$done({body: JSON.stringify(body)})

แก้ไขเนื้อหาคำขอก่อนส่ง

สคริปต์ http-request-before-send ที่ทำความสะอาดเพย์โหลด POST:

[Script]
SanitizePayload = type=http-request-before-send, script-path=sanitize.js, pattern=^https://api\.example\.com/submit, requires-body=true
// sanitize.js
var body = JSON.parse($request.body)
body.clientSecret = "[REDACTED]"
body.timestamp = Math.floor(Date.now() / 1000)
$done({body: JSON.stringify(body)})

กฎกำหนดเอง: การจัดเส้นทางตามเวลา

สคริปต์ rule ที่เลือกพร็อกซีที่แตกต่างกันขึ้นอยู่กับช่วงเวลาของวัน:

[Rule]
SCRIPT,TimeBasedRule,ProxyA

[Script]
TimeBasedRule = type=rule, script-path=time-rule.js
// time-rule.js
var hour = new Date().getHours()
if (hour >= 9 && hour < 18) {
    $done({matched: false})  // ส่งต่อไปยังกฎถัดไปในช่วงเวลาทำงาน
} else {
    $done({matched: true})   // ใช้ ProxyA ในช่วงนอกเวลาทำงาน
}

DNS กำหนดเองสำหรับโดเมนภายใน

สคริปต์ dns ที่แก้ไขชื่อโฮสต์ภายในเป็น IP ในเครื่อง:

[Script]
InternalDNS = type=dns, script-path=internal-dns.js
// internal-dns.js
var internalHosts = {
    "gitlab.local": "10.0.0.10",
    "registry.local": "10.0.0.11",
    "monitor.local": "10.0.0.12"
}
if (internalHosts[$domain]) {
    $done({address: internalHosts[$domain], ttl: 3600})
} else {
    $done({})  // ส่งผ่านไปยัง DNS ปกติ
}

สลับนโยบายอัตโนมัติเมื่อเปลี่ยนเครือข่าย

สคริปต์ event ที่ตรวจสอบการเชื่อมต่อหลังเครือข่ายเปลี่ยน แล้วสลับกลุ่มนโยบายตามผลลัพธ์:

[Script]
NetSwitch = type=event, script-path=network-switch.js
// network-switch.js
$httpClient.head("https://www.google.com/generate_204", {timeout: 5},
    function(error, response, data) {
        if (error) {
            // การตรวจสอบล้มเหลวบนเครือข่ายใหม่ — สลับไปยังกลุ่มสำรอง
            $klne.selectPolicy("MainGroup", "BackupProxy")
            console.log("Probe failed after " + $event.name)
        } else {
            $klne.selectPolicy("MainGroup", "MainProxy")
        }
        $done({})
    })

ข้อสังเกต: การอ่าน SSID ของ Wi-Fi ผ่าน $network เป็นวิธีที่เป็นธรรมชาติที่สุดสำหรับกรณีนี้ แต่ปัจจุบัน $network ยังมองไม่เห็นจากสคริปต์ (ดูข้อสังเกตใน $network) ในรุ่นปัจจุบันให้ใช้การตรวจสอบผ่าน $httpClient แทน

ตรวจสอบสุขภาพเป็นระยะ

สคริปต์ cron ที่ตรวจสอบสุขภาพพร็อกซีทุก 30 นาที:

[Script]
HealthCheck = type=cron, script-path=health-check.js, cron-expression=*/30 * * * *
// health-check.js
$httpClient.head("https://www.google.com/generate_204", {timeout: 10},
    function(error, response, data) {
        if (error || response.status !== 204) {
            console.error("Health check failed: " + (error || "status " + response.status))
            $notification.post("Chute Alert", "Health Check", "Cannot reach Google")
        } else {
            console.log("Health check OK")
        }
        $done({})
    }
)

เรียก $done({}) ภายใน callback — การจบสคริปต์จะยกเลิกคำขอ $httpClient ที่ค้างอยู่ทั้งหมด ดังนั้นการเรียก $done() แบบซิงโครนัสที่ท้ายสคริปต์จะยกเลิกการตรวจสอบสุขภาพก่อนที่การตอบกลับจะมาถึง

เพิ่มข้อมูลการตอบกลับ API ด้วยข้อมูลภายนอก

สคริปต์ http-response ที่เพิ่มข้อมูลผู้ใช้โดยเรียก API รอง:

[Script]
EnrichUsers = type=http-response, script-path=enrich.js, pattern=^https://api\.example\.com/users, requires-body=true
// enrich.js
var users = JSON.parse($response.body)
var pending = users.length
if (pending === 0) { $done({}) }

users.forEach(function(user, index) {
    $httpClient.get("https://internal-api.example.com/avatar/" + user.id,
        function(error, resp, data) {
            if (!error && resp.status === 200) {
                users[index].avatar = JSON.parse(data).url
            }
            pending--
            if (pending === 0) {
                $done({body: JSON.stringify(users)})
            }
        }
    )
})

โมเดลการทำงาน

  • สคริปต์ทั้งหมดทำงานบนคิวอนุกรมเฉพาะเพื่อความปลอดภัยของเธรด
  • การทำงานของสคริปต์แต่ละครั้งมีเวลาหมดต่อสคริปต์ หาก $done() ไม่ถูกเรียกภายในเวลาหมด สคริปต์จะถูกปฏิบัติเป็นส่งผ่าน
  • มีการเก็บพูล JSContext ที่อุ่นเครื่องไว้ล่วงหน้า 3 ตัว; คอนเท็กซ์จะถูกทิ้งหลังการทำงานแต่ละครั้งและแทนที่ด้วยตัวใหม่ ดังนั้นตัวแปรส่วนกลางจะไม่รั่วไหลระหว่างการทำงาน
  • บน iOS/tvOS สคริปต์อยู่ภายใต้ขีดจำกัดหน่วยความจำ 10MB; บน macOS 512MB
  • สคริปต์ระยะไกล (เส้นทาง HTTP/HTTPS) ถูกดึงในทุกการทำงาน เมื่อ script-update-interval ไม่เป็นศูนย์ Chute จะสำรวจ URL เพิ่มเติมด้วยคำขอ HEAD แบบมีเงื่อนไขทุก 10 นาที; 0 (ค่าเริ่มต้น) ปิดใช้งานการสำรวจ

การรวมสคริปต์โมดูล

สคริปต์ยังสามารถกำหนดในไฟล์ โมดูล (.sgmodule) ภายใต้ส่วน [Script]

S. Smart Rabbit LLC © All Rights Reserved            updated 2026-08-18 12:04:25

หน้านี้เป็นฉบับแปลจากเวอร์ชันภาษาอังกฤษ หากเนื้อหาไม่ตรงกัน ให้ยึดเวอร์ชันภาษาอังกฤษเป็นหลัก

results matching ""

    No results matching ""