microdot.cors --- مشاركة الموارد عبر المصادر (CORS)

يضيف الترويسات التي يحتاجها المتصفح للسماح لـ JavaScript الذي يعمل على مصدر واحد باستدعاء نقاط النهاية المستضافة على الكاميرا على مصدر مختلف. يربط الصنف نفسه في معالج OPTIONS للتطبيق (لطلبات الفحص المسبق) وفي خطاف ما بعد الطلب (لترويسات Access-Control-* على الاستجابات العادية).

class CORS

class microdot.cors.CORS(app: Microdot | None = None, allowed_origins=None, allow_credentials: bool = False, allowed_methods: list | None = None, expose_headers: list | None = None, allowed_headers: list | None = None, max_age: int | None = None, handle_cors: bool = True)
app

نسخة microdot.Microdot المراد الربط بها. قد تكون None لتأجيل الربط؛ استدعِ initialize() لاحقاً.

allowed_origins

قائمة بسلاسل المصادر (["https://app.example.com"]) أو الحرفية '*' للسماح بأي مصدر. المصادر التي لا تطابق هذه القائمة لا تحصل على ترويسات CORS، وهو ما يفسره المتصفح على أنه "هذا الطلب غير مسموح به".

allow_credentials

إذا كانت True، يضيف Access-Control-Allow-Credentials: true لكي يرسل المتصفح ملفات تعريف الارتباط وترويسات المصادقة مع الطلبات عبر المصادر. لا يمكن استخدامها مع allowed_origins='*' لأي طلب يحتاج إلى بيانات اعتماد (ترفض المتصفحات هذا الدمج).

allowed_methods

قائمة بالطرق (['GET', 'POST']) التي قد يستخدمها المتصفح عبر المصادر. تعني None أي طريقة.

expose_headers

قائمة بأسماء ترويسات الاستجابة التي قد يكشفها المتصفح لـ JavaScript.

allowed_headers

قائمة بأسماء ترويسات الطلب التي قد يضمنها العملاء عبر المصادر. تعني None أياً منها (تردد صدى Access-Control-Request-Headers للفحص المسبق).

max_age

عدد الثواني التي قد يخزن فيها المتصفح نتيجة الفحص المسبق مؤقتاً. تخطيها يعني أن المتصفح يعيد التحقق من كل فحص مسبق.

handle_cors

إذا كانت False، يُهيّأ الصنف لكنه لا يربط نفسه فعلياً -- مفيد عندما تريد دمج مخرجات get_cors_headers() يدوياً مع برمجيات وسيطة أخرى.

initialize(app: Microdot, handle_cors: bool = True)

الربط بـ app إذا كان البناء قد أُجِّل.

get_cors_headers(request) dict

حساب مجموعة ترويسات Access-Control-* التي تنطبق على request. يُستخدم داخلياً بواسطة خطاف ما بعد الطلب؛ ويمكن للتطبيقات استدعاؤه مباشرة عند إصدار ترويسات CORS من برمجية وسيطة مخصصة.

allowed_origins: list | str | None

قائمة المصادر المُهيأة، أو الحرفية '*'. تعكس وسيط المُنشئ allowed_origins؛ أعد تعيينها أثناء التشغيل لتغيير السياسة دون إعادة بناء الكائن.

allow_credentials: bool

ما إذا كانت Access-Control-Allow-Credentials: true تُصدَر على الطلبات المطابقة. تعكس وسيط المُنشئ allow_credentials.

allowed_methods: list | None

قائمة بأسماء الطرق المسموح بها عبر المصادر، أو None لتعني "أياً منها". تعكس وسيط المُنشئ allowed_methods.

expose_headers: list | None

قائمة بترويسات الاستجابة التي قد يكشفها المتصفح لـ JavaScript، أو None لحذف ترويسة Access-Control-Expose-Headers. تعكس وسيط المُنشئ expose_headers.

allowed_headers: list | None

قائمة بأسماء ترويسات الطلب المقبولة عبر المصادر، بحروف صغيرة، أو None لتعني "كرر صدى أياً كان ما طلبه الفحص المسبق". تعكس وسيط المُنشئ allowed_headers (يحوّل المُنشئ القائمة إلى حروف صغيرة قبل تخزينها).

max_age: int | None

عدد الثواني التي قد يخزن فيها المتصفح استجابة الفحص المسبق مؤقتاً، أو None لحذف ترويسة Access-Control-Max-Age. تعكس وسيط المُنشئ max_age.

مثال:

from microdot import Microdot
from microdot.cors import CORS

app = Microdot()
CORS(app,
     allowed_origins=['https://dashboard.example.com'],
     allow_credentials=True,
     max_age=86400)

@app.get('/api/status')
async def status(request):
    return {'ok': True}

تُعالَج طلبات الفحص المسبق OPTIONS تلقائياً؛ تُرجع الكاميرا ترويسات Access-Control-* المناسبة و 204 No Content. أما الاستجابات الفعلية لـ GET / POST / إلخ فتلتقط ترويسة Access-Control-Allow-Origin عبر خطاف ما بعد الطلب المسجل.