الوثائقوسائط
SSR (عرض الخادم)
التعريف
SSR هو الإعداد الافتراضي: يعرض الخادم الصفحة بتنسيق HTML لكل طلب. لا شيء يمكّنه، ولا توجد علامة تطفئه - يتم عرض مشروع وضع الخادم عند كل طلب ما لم تعلن الصفحة عن revalidate.
كيف يعمل
| ملف الطريق | ما الذي ينتج HTML | متى |
|---|---|---|
.nexy |
الوحدة Python المترجمة، من خلال Jinja2 | كل طلب |
.md |
Markdown، ثم أقرب تخطيط | كل طلب |
.mdx، .tsx، .vue، .svelte |
الإطار المقدم في Node | عند الإنشاء عندما لا يكون للمسار أي تخطيط، وإلا في المتصفح |
.py |
لا شيء: يقوم بإرجاع JSON أو Response |
- |
صفحة Markdown ومعالج جنبًا إلى جنب في نفس المشروع:
# Changelog Rendered to HTML on every request, then wrapped in the nearest layout.async def GET(): return {"status": "ok"}المسار المكون هو الحالة الوحيدة التي تحتاج إلى جملة ثانية. في الإنتاج، يتم تقديم مسار المكون بدون تخطيطًا مع HTML الذي تم إنتاجه عند الإنشاء، ويقوم المكون بترطيبه. مع التخطيط، أو قيد التطوير، تكون الحاوية فارغة ويتم عرض المكون في المتصفح - تصبح الصفحة بعد ذلك عبارة عن غلاف يملأ نفسه.
المسار المكون للجدول، بدون تخطيط، لذلك يخدم الإنتاج HTML الخاص به من الإصدار:
export default function Pricing() { return <h1>Pricing</h1>;}| تعود وحدة التحكم | ما الذي ينتج HTML | متى |
|---|---|---|
useViews("....nexy") |
الوحدة النمطية Python المترجمة، من خلال Jinja2 | كل طلب |
dict، قائمة، نموذجا |
لا شيء: FastAPI يجيب على JSON | - |
عرض ونقطة نهاية JSON، جنبًا إلى جنب في نفس الوحدة:
<h1>Changelog</h1><p>Rendered to HTML on every request.</p>from nexy.decorators import Controllerfrom nexy.hooks import useViews @Controller("/changelog")class ChangelogController: async def get(self): return useViews("src/apps/changelog_view.nexy") @Controller("/api/health")class HealthController: async def get(self): return {"status": "ok"}تقديم دورة الحياة
-
يصل الطلب إلى جهاز التوجيه المستند إلى الملف. تتم مطابقة المسار، ويتم إرسال المقاطع الديناميكية إلى الأنواع التي يعلنها المكون.
--- المعرف: الدعامة [int] --- <h1>الطلب رقم {{ المعرف + 1000 }}</h1>/orders/42يعرضOrder #1042؛/orders/abcالإجابات404. -
يعمل المكون. يتم تشغيل المستند الذي ينتظر على العقدة - وهو مستند العميل - في تجمع مؤشرات الترابط، لذلك لا يوقف حلقة الحدث.
-
الجسد متدفق كما
text/html. المكون الذي ينتج قطعًا يقوم بدفقها أثناء تصنيعها. -
يتلقى المتصفح HTML. هيدرات الجزر حسب التوجيه.
يتم تحويل الخطأ الذي يظهر أثناء العرض إلى صفحة بواسطة errors.nexy عندما يكون لدى المشروع صفحة: راجع صفحات الخطأ.
-
يصل الطلب إلى وحدة التحكم. يتم إرسال معلمات المسار الخاصة بها إلى الأنواع التي تعلن عنها الطريقة، وتمريرها إلى العرض:
من وحدة تحكم الاستيراد nexy.decorators من nexy.hooks قم باستيراد useViews @Controller("/الطلبات/{id}") وحدة تحكم ترتيب الفئة: الحصول على مواطن غير متزامن (self، id: int): إرجاع useViews("src/apps/order_view.nexy"، context={"id": id})--- المعرف: الدعامة [int] --- <h1>الطلب رقم {{ المعرف + 1000 }}</h1>/orders/42/يعرضOrder #1042؛/orders/abc/الإجابات404. -
يتم تشغيل العرض، ويقوم
useViewsبإرجاع HTML الخاص به كاستجابة. -
يتلقى المتصفح HTML. هيدرات الجزر حسب التوجيه.
يتم الرد على الخطأ الذي يظهر أثناء العرض باستخدام صفحة الخطأ الافتراضية.
متى تستخدم
- تعرض الصفحة شيئًا يملكه القارئ: جلسة، حساب، عربة.
- يجب أن تكون البيانات جديدة عند كل تحميل.
- يجب أن يكون المحتوى بتنسيق HTML لبرامج الزحف التي لا تعمل JavaScript.
- الصفحة رخيصة الثمن: استعلام واحد، قالب واحد.
الحالة الأولى، صفحة تحية للقارئ من الجلسة. useSession يقرأ جلسة useSession في nexyconfig.py، والتي بدونها يفشل:
from nexy.core.models import NexyConfigModel class NexyConfig(NexyConfigModel): useSession = {"secret_key": "change-me"}from nexy import useSession user = useSession().get("user", "guest")<h1>Signed in as {{ user }}</h1>from nexy import useSession user = useSession().get("user", "guest")<h1>Signed in as {{ user }}</h1>التكوين
لا شيء. هناك طريقان، وليس لديهم نفس الحبوب:
| لترك SSR ل | افعل هذا | الحبوب |
|---|---|---|
| صفحة واحدة، مع ذاكرة التخزين المؤقت | revalidate = 60 في مقدمتها → ISR |
الصفحة |
| المشروع بأكمله، توجيه العميل | useCSR = True في nexyconfig.py → المسؤولية الاجتماعية للشركات |
مشروع |
التبديل على مستوى المشروع، في nexyconfig.py. يحتاج وضع العميل إلى إطار عمل العميل:
from nexy.core.models import NexyConfigModelfrom nexy.frontend import react class NexyConfig(NexyConfigModel): useFF = react() useCSR = Trueلا شيء. يتم تقديم كل عرض ترجعه وحدة التحكم عند كل طلب: ISR و CSR هما وضعان لجهاز التوجيه المستند إلى الملف.
مثال
slug: prop[str] = "untitled"<h1>{{ slug }}</h1>GET /blog/hello يقوم بتشغيل هذا القالب مرة واحدة، مع ضبط slug على hello. الطلب الثاني يقوم بتشغيله مرة أخرى: لا يتم الاحتفاظ بأي شيء بين الاثنين. سلسلة الاستعلام ليست دعامة - اقرأها باستخدام الخطافات في التنقل.
from nexy.decorators import Controllerfrom nexy.hooks import useViews @Controller("/blog/{slug}")class PostController: async def get(self, slug: str): return useViews("src/apps/post_view.nexy", context={"slug": slug})slug: prop[str] = "untitled"<h1>{{ slug }}</h1>GET /blog/hello/ يقوم بتشغيل هذا العرض مرة واحدة، مع ضبط slug على hello. الطلب الثاني يقوم بتشغيله مرة أخرى: لا يتم الاحتفاظ بأي شيء بين الاثنين. سلسلة الاستعلام ليست دعامة - اقرأها باستخدام useSearchParams.
القيود
- عرض واحد لكل طلب. زائران في نفس الثانية يدفع كل منهما ثمن العرض والاستعلامات التي تقف وراءه.
- لا توجد ذاكرة تخزين مؤقت. لا توجد ذاكرة تخزين مؤقت للاستجابة المشتركة لتدفئة: مع مسارات الملفات، يضيف ISR واحدًا لكل عنوان URL.
- يساعد الدفق فقط المكون الذي ينتج. لا يزال الاستعلام البطيء الموجود أعلى الصفحة يؤخر البايت الأول.
- لا يوجد إخراج ثابت. في وضع الخادم، لا يتم تجميد أي شيء عند الإنشاء: لا يوجد وضع SSG، ولا يوجد أمر تصدير. انظر التقديم.
- تم إيقاف ميزة الهروب التلقائي في
.nexyالقوالب. الهروب من القيم غير الموثوق بها مع| e.
from nexy import useSearchParams q = useSearchParams().get("q", "")<p>Results for {{ q | e }}</p>from nexy import useSearchParams q = useSearchParams().get("q", "")<p>Results for {{ q | e }}</p>الخطوات التالية
- ISR: قم بتخزين هذه الصفحة لكل عنوان URL
- الجزر: احتفظ بـ SSR واجعل عنصر واجهة مستخدم واحدًا تفاعليًا
- CSR: التنقل اليدوي إلى المتصفح