برمجة JavaScript

يدعم Chute برمجة JavaScript لتعديل الطلبات/الاستجابات المتقدم، مطابقة القواعد المخصصة، تحليل DNS، والمهام المجدولة. تستخدم السكريبتات محرك Apple JavaScriptCore وتتبع واجهة برمجة السكريبتات المتوافقة مع 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, debug=true
CronJob = type=cron, script-path=/path/to/cron.js, cron-expression=* * * * *, wake-system=true

معاملات السكريبت

المعامل مطلوب الافتراضي الوصف
type نعم http-request نوع تشغيل السكريبت (انظر أدناه)
script-path نعم مسار ملف محلي أو رابط HTTP(S) لسكريبت JS
pattern لا (مطابقة الكل) نمط رابط بتعبير نمطي لتصفية وقت تشغيل السكريبت
requires-body لا اكتشاف تلقائي فرض استلام السكريبت لمحتوى الطلب/الاستجابة الكامل
max-size لا 131072 (128KB) الحد الأقصى لحجم المحتوى بالبايت للسكريبتات التي تصل للمحتوى
timeout لا 5.0 ثانية مهلة تنفيذ لكل سكريبت
argument لا نص وسيط مخصص متاح كـ $argument في JS
debug لا false تخطي ذاكرة التخزين المؤقتة للترجمة للتصحيح
cron-expression لا تعبير جدولة cron (لنوع cron فقط)
wake-system لا false إيقاظ النظام لتنفيذ سكريبتات cron (iOS فقط)
enable لا true تفعيل أو تعطيل هذا السكريبت
script-update-interval لا 0 ثواني بين تحديثات السكريبتات البعيدة (-1 = أبداً، 0 = فقط عند البدء)

أنواع السكريبتات

النص النوعي التعداد الوصف
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 لفرض هذا السلوك.


مرجع JavaScript API

تعمل السكريبتات في بيئة JavaScriptCore معزولة مع توفر الكائنات العامة التالية.

$request (للقراءة فقط)

متوفر في: http-request, http-response, http-request-before-send, rule

الخاصية النوع الوصف
.url String رابط الطلب الكامل
.method String طريقة HTTP (GET, POST, إلخ) أو QUERY لـ DNS
.headers Object ترويسات الطلب كأزواج key-value
.body String or null محتوى الطلب (مفكوك UTF-8)
.hostname String اسم المضيف الهدف
.destPort Number منفذ الوجهة
.processPath String مسار العملية الطالبة (macOS فقط)
.userAgent String قيمة ترويسة User-Agent
.sourceIP String عنوان IP المصدر
.listenPort Number منفذ استماع البروكسي
.requestId String معرف طلب فريد
.dnsResult String عنوان IP المحلل
.srcPort Number منفذ المصدر
.protocol String البروتوكول المكتشف: http, https, tcp, dns

$response (للقراءة فقط)

متوفر في: http-response

الخاصية النوع الوصف
.status Number رمز حالة HTTP
.headers Object ترويسات الاستجابة كأزواج key-value
.body String or null محتوى الاستجابة (مفكوك UTF-8)

$done(value) — معالج الإكمال

يجب استدعاؤه مرة واحدة بالضبط في نهاية السكريبت للإشارة إلى الاكتمال. يتوقف تنفيذ السكريبت حتى يتم استدعاء $done() أو انتهاء المهلة.

$done({})                        // تمرير — لا تعديلات
$done()                          // إجهاض الاتصال
$done({matched: true})           // نتيجة مطابقة القاعدة (لسكريبتات القواعد فقط)
$done({address: "1.2.3.4"})      // نتيجة DNS (لسكريبتات DNS فقط)

قيم إرجاع سكريبت طلب HTTP:

$done({
    url: "https://new.example.com/path",     // إعادة كتابة الرابط
    headers: {"X-Custom": "value"},           // تعديل الترويسات
    body: "new request body",                 // تعديل المحتوى
    response: {                               // إرجاع استجابة اصطناعية (تخطي الخادم العلوي)
        status: 200,
        headers: {"Content-Type": "text/html"},
        body: "<html>Blocked</html>"
    }
})

عند توفير response، يتم اختصار الطلب: يرجع Chute الاستجابة الاصطناعية مباشرة إلى العميل دون الاتصال بالخادم العلوي. هذا مفيد للحظر، محاكاة APIs، أو إرجاع محتوى مخزن مؤقتاً.

قيم إرجاع سكريبت استجابة HTTP:

$done({
    status: 200,                              // تعديل رمز الحالة
    headers: {"X-Custom": "value"},           // تعديل ترويسات الاستجابة
    body: "new response body",                // تعديل محتوى الاستجابة
    url: "https://other.example.com"          // تشغيل إعادة توجيه 302
})

عند توفير url، يرجع Chute إعادة توجيه 302 إلى الرابط المعطى بدلاً من الاستجابة الأصلية.

قيم إرجاع سكريبت DNS:

$done({address: "1.2.3.4"})                  // IP واحد
$done({addresses: ["1.2.3.4", "5.6.7.8"]})   // عدة IPs
$done({address: "10.0.0.1", ttl: 300})       // مع TTL مخصص (بالثواني، الافتراضي 60)
$done({server: "8.8.8.8"})                   // توجيه إلى خادم DNS محدد

$httpClient — عميل HTTP غير متزامن

إجراء طلبات 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

$persistentStore — تخزين Key-Value

تخزين key-value دائم يبقى عبر إعادة تشغيل السكريبتات والعمليات. مدعوم بـ 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: "aa:bb:cc:dd:ee:ff"}

$environment — معلومات وقت التشغيل

$environment.system     // "iOS" أو "macOS"
$environment.appVersion // نص إصدار التطبيق

$utils — أدوات مساعدة

$utils.geoip("1.2.3.4")   // رمز الدولة (مثال: "US")
$utils.ipasn("1.2.3.4")   // رقم ASN (مثال: "13335")
$utils.ungzip(data)       // فك ضغط بيانات gzip

$klne — واجهة التحكم بالبروكسي

التحكم في وقت تشغيل البروكسي من السكريبتات.

$klne.policyGroups                    // الحصول على جميع مجموعات السياسات
$klne.selectPolicy("Group", "Proxy")  // تبديل سياسة لمجموعة
$klne.getActiveConnections()          // سرد الاتصالات النشطة
$klne.closeConnection("id")           // إغلاق اتصال
$klne.flushDNS()                      // مسح ذاكرة DNS المؤقتة
$klne.startURLTest("Group")           // تشغيل اختبار رابط لمجموعة
$klne.reloadConfiguration()           // إعادة تحميل جميع الإعدادات
$klne.setOutboundMode("rule")         // تعيين النمط: "global", "proxy", "direct", "rule"
$klne.setHTTPCaptureEnabled(true)     // تفعيل/تعطيل MITM

$script — بيانات السكريبت الوصفية

$script.name       // اسم السكريبت من الإعدادات
$script.type       // نص نوع السكريبت
$script.startTime  // طابع زمني epoch

globals لكل تنفيذ

يتم حقن المتغيرات التالية لكل تنفيذ سكريبت وهي خاصة بأنواع سكريبتات معينة.

$argument — وسيط السكريبت

القيمة النصية من معامل argument= في إعدادات السكريبت. متوفر في: http-request, http-response, http-request-before-send, rule, dns, cron.

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")   // سجل تحذيري ببادئة [JS-ERROR]

setTimeout(fn, seconds) — مؤقت

جدولة دالة للتشغيل بعد تأخير.

setTimeout(function() {
    console.log("Delayed execution")
}, 2.5)  // 2.5 ثانية

$script(subScriptPath) — محمل السكريبتات الفرعية

تحميل وتقييم ملف JavaScript آخر.

$script("/path/to/helper.js")
$script("https://example.com/remote-script.js")

// تمرير البيانات بين السكريبتات باستخدام $persistentStore

تفاصيل أنواع السكريبتات

سكريبت طلب HTTP

ينفذ عند استلام ترويسات الطلب. يمكنه تعديل الرابط، الترويسات، والمحتوى قبل توجيه الطلب.

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

سكريبت استجابة HTTP

ينفذ عند استلام ترويسات الاستجابة. يمكنه تعديل الحالة، الترويسات، والمحتوى قبل الإرجاع إلى العميل.

[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

سكريبت القاعدة

مطابقة قواعد مخصصة. يجب على السكريبت استدعاء $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]
HourlyTask = type=cron, script-path=hourly.js, cron-expression=0 * * * *

صيغة cron المبسطة مدعومة (مثال: */30 * * * * لكل 30 دقيقة، قيم مفصولة بفواصل).

سكريبت الحدث

يتم تشغيله بواسطة أحداث النظام. حالياً يدعم حدث network-changed (ينطلق عند تغير شبكة WiFi أو الجوال).

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

كائن $event متاح:

$event.name  // "network-changed"

أمثلة عملية

Redirect Mobile Devices

سكريبت 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({})
}

Block Content in API Responses

سكريبت 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)})

Modify Request Body Before Sending

سكريبت 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)})

Custom Rule: Time-Based Routing

سكريبت 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 خارج ساعات العمل
}

Custom DNS for Internal Domains

سكريبت 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 العادي
}

Auto-Switch Policy on Network Change

سكريبت event يبدل إلى مجموعة سياسات محافظة عند استخدام الجوال:

[Script]
NetSwitch = type=event, script-path=network-switch.js
// network-switch.js
if (!$network.wifi.ssid) {
    // على الجوال — استخدام مجموعة بيانات منخفضة
    $klne.selectPolicy("MainGroup", "LowDataProxy")
    console.log("Switched to cellular profile")
} else if ($network.wifi.ssid === "Office") {
    $klne.selectPolicy("MainGroup", "DIRECT")
    console.log("Switched to office profile")
}

Periodic Health Check

سكريبت 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()

Enrich API Responses with External Data

سكريبت 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) للأداء؛ يتم إعادة استخدام السياقات عبر التنفيذات.
  • ترجمة السكريبتات مخزنة مؤقتاً افتراضياً؛ استخدم debug=true لتجاوز التخزين المؤقت.
  • على iOS/tvOS، تخضع السكريبتات لحد ذاكرة 10MB؛ على macOS، 512MB.
  • السكريبتات البعيدة (مسارات HTTP/HTTPS) تجلب عند البدء ويمكن إعادة جلبها اختيارياً كل script-update-interval ثانية.

دمج سكريبتات الوحدات

يمكن أيضاً تعريف السكريبتات في ملفات Module (.sgmodule) تحت القسم [Script].

S. Smart Rabbit LLC © All Rights Reserved            updated 2026-06-28 02:09:17

results matching ""

    No results matching ""