Node.js/Express.js-كيف يعمل app.router؟




middleware (2)

يعني "التوجيه" تحديد كيفية استجابة أحد التطبيقات لطلب العميل إلى نقطة نهاية معينة ، وهو URI (أو المسار) وطريقة طلب HTTP معينة (GET و POST وما إلى ذلك). يمكن أن يحتوي كل مسار على واحد أو أكثر من وظائف المعالج ، والتي يتم تنفيذها عند مطابقة المسار.

في Express 4.0 Router ، يتم منحنا مرونة أكثر من أي وقت مضى في تحديد مساراتنا.

express.Router () يستخدم عدة مرات لتحديد مجموعات من الطرق.

الطريق المستخدمة باعتبارها الوسيطة لمعالجة الطلبات.

الطريق المستخدمة باعتبارها وسيطة للتحقق من صحة المعلمات باستخدام ".param ()".

يستخدم app.route () كاختصار لجهاز التوجيه لتحديد طلبات متعددة على الطريق

عندما نستخدم app.route () ، فإننا نربط تطبيقنا مع ذلك الموجه.

var express = require('express'); //used as middleware
var app = express(); //instance of express.
app.use(app.router);
app.use(express.static(__dirname + '/public')); //All Static like [css,js,images] files are coming from public folder
app.set('views',__dirname + '/views'); //To set Views
app.set('view engine', 'ejs'); //sets View-Engine as ejs
app.engine('html', require('ejs').renderFile); //actually rendering HTML files through EJS. 
app.get('/', function (req, res) {
  res.render('index');  
})
app.get('/test', function (req, res) {
  res.send('test')
})

قبل أن أسأل عن app.router أعتقد أنني يجب أن أشرح على الأقل ما أعتقد أنه يحدث عند العمل مع الوسيطة. لاستخدام الوسيطة ، فإن الوظيفة المراد استخدامها هي app.use() . عندما يتم تنفيذ الوسيطة ، سوف يقوم إما باستدعاء الوسيطة next() باستخدام next() أو جعله حتى لا يتم الاتصال بأي وسيط آخر. وهذا يعني أن الترتيب الذي أضع مكالمات الوسيطة فيه أمر مهم ، لأن بعض البرامج الوسيطة تعتمد على البرامج الوسيطة الأخرى ، وربما لا يتم حتى استدعاء بعض البرامج الوسيطة القريبة من النهاية.

اليوم كنت أعمل على طلبي وكان خادمي يعمل في الخلفية. أردت إجراء بعض التغييرات وتحديث صفحتي ورؤية التغييرات على الفور. على وجه التحديد ، كنت أقوم بإجراء تغييرات على تخطيطي. لم أتمكن من الوصول إلى العمل لذلك بحثت في Stack Overflow عن الإجابة ووجدت هذا السؤال . تقول للتأكد من أن express.static() تحت require('stylus') . ولكن عندما كنت أبحث في رمز OP هذا ، رأيت أنه كان له app.router في نهاية نداءاته الوسيطة ، وحاولت معرفة السبب في ذلك.

عندما جعلت تطبيق Express.js الخاص بي (الإصدار 3.0.0rc4) ، استعملت الأوامر express app --sessions --css stylus وفي ملف app.js الخاص بي جاء رمز الإعداد مع app.router أعلاه على حد سواء express.static() require('stylus') المكالمات. لذا يبدو الأمر كذلك ، إذا كان قد تم إعداده بالفعل بهذه الطريقة ، فيجب أن يبقى كذلك.

بعد إعادة ترتيب الشفرة حتى أتمكن من رؤية تغيير Stylus ، يبدو الأمر كما يلي:

app.configure(function(){
  //app.set() calls
  //app.use() calls
  //...
  app.use(app.router);
  app.use(require('stylus').middleware(__dirname + '/public'));
  app.use(express.static(__dirname + '/public', {maxAge: 31557600000}));
});

app.get('/', routes.index);

app.get('/test', function(req, res){
  res.send('Test');
});

لذلك قررت أن الخطوة الأولى هي معرفة سبب أهمية وجود app.router في app.router . لذلك علّقت بذلك ، وبدأت تطبيقي وواصلت إلى / . لقد عرضت صفحة الفهرس الخاصة بي على ما يرام. حسنًا ، ربما كان ذلك ناجحًا لأنني كنت أقوم بتصدير التوجيه من ملف المسارات (path.index). بعد ذلك ، انتقلت إلى /test وعرضت الاختبار على الشاشة. هاها ، حسنا ، ليس لدي أي فكرة عما يفعله app.router . سواء كان مدرجًا في الكود أم لا ، فإن توجيهاتي جيد. لذلك أنا في عداد المفقودين شيء بالتأكيد.

حتى هنا هو سؤالي:

هل يمكن لشخص ما أن يشرح ما هو app.router ، وأهمية ذلك ، وأين يجب أن app.router الوسيطة؟ سيكون من الجميل أيضا إذا كان لدي شرح موجز عن express.static() . بقدر ما أستطيع أن أقول ، express.static() هو ذاكرة تخزين مؤقت للمعلومات الخاصة بي ، وإذا لم يتمكن التطبيق من العثور على الصفحة المطلوبة ، فإنه سيتم التحقق من ذاكرة التخزين المؤقت لمعرفة ما إذا كان موجودًا.


ملاحظة: يصف هذا كيفية عمل Express في الإصدارين 2 و 3. راجع نهاية هذه المشاركة للحصول على معلومات حول Express 4.

static ببساطة يخدم الملفات (الموارد الثابتة ) من القرص. يمكنك إعطاؤه مسارًا (يطلق عليه أحيانًا نقطة التحميل) ، ويخدم الملفات في هذا المجلد.

على سبيل المثال ، يمكن لـ express.static('/var/www') أن تخدم الملفات الموجودة في هذا المجلد. لذلك فإن طلب خادم Node الخاص بك http://server/file.html سيخدم /var/www/file.html .

router هو رمز يقوم بتشغيل المسارات الخاصة بك. عندما تقوم app.get('/user', function(req, res) { ... }); ، هو router الذي يستدعي فعليًا وظيفة رد الاتصال لمعالجة الطلب.

يحدد الترتيب الذي تمرر به الأشياء إلى app.use الترتيب الذي يتم من خلاله منح كل برنامج app.use الفرصة لمعالجة الطلب. على سبيل المثال ، إذا كان لديك ملف يسمى test.html في مجلدك الثابت ومسار:

app.get('/test.html', function(req, res) {
    res.send('Hello from route handler');
});

ما الذي يتم إرساله إلى العميل لطلب http://server/test.html ؟ يتم إعطاء أي وسيط use المقام الأول.

إذا قمت بذلك:

app.use(express.static(__dirname + '/public'));
app.use(app.router);

ثم يتم تقديم الملف على القرص.

إذا كنت تفعل ذلك في الاتجاه الآخر ،

app.use(app.router);
app.use(express.static(__dirname + '/public'));

ثم يحصل معالج التوجيه على الطلب ، ويتم إرسال "مرحبًا من معالج التوجيه" إلى المتصفح.

عادة ، تريد وضع جهاز التوجيه فوق الوسيطة الثابتة بحيث لا يمكن لملف مسمى عن طريق الخطأ تجاوز أحد مساراتك.

لاحظ أنه إذا لم use router بشكل صريح ، فسيتم إضافته بشكل ضمني بواسطة Express عند النقطة التي تحددها للمسار (وهو السبب في أن المسارات الخاصة بك لا تزال تعمل حتى إذا قمت بالتعليق على app.use(app.router) ).

لقد طرح أحد المعلقين نقطة أخرى حول ترتيب router الذي لم أتطرق إليه: التأثير على الأداء العام لتطبيقك.

سبب آخر use router أعلاه static هو تحسين الأداء. إذا وضعت static أولاً ، فستضرب محرك الأقراص الثابتة في كل طلب لمعرفة ما إذا كان الملف موجودًا أم لا. في اختبار سريع ، وجدت أن هذه النفقات العامة بلغت ~ 1ms على خادم تفريغ. (من المرجح أن يكون هذا الرقم أعلى تحت الحمل ، حيث ستتنافس الطلبات على الوصول إلى القرص.)

باستخدام router أولاً ، لن يضطر أحد التطبيقات المطابقة لمسار مطلق إلى الوصول إلى القرص مطلقًا ، مما يؤدي إلى توفير أجزاء من المللي ثانية.

بالطبع ، هناك طرق للتخفيف من النفقات العامة الثابتة.

الخيار الأفضل هو وضع كافة الموارد الثابتة ضمن مجلد محدد. (IE /static ) يمكنك بعد ذلك تركيب static على هذا المسار بحيث يتم تشغيله فقط عندما يبدأ المسار بـ /static :

app.use('/static', express.static(__dirname + '/static'));

في هذه الحالة ، يمكنك وضع هذا router أعلاه. هذا يتجنب معالجة البرامج الوسيطة الأخرى / الموجه إذا كان الملف موجودًا ، ولكن لأكون صادقًا ، أشك في أنك ستكسب هذا القدر.

يمكنك أيضًا استخدام staticCache ، الذي يخزن الموارد الثابتة في الذاكرة بحيث لا تضطر إلى staticCache على القرص للملفات المطلوبة بشكل شائع. ( تحذير: ستتم إزالة staticCache في المستقبل على ما يبدو .)

ومع ذلك ، لا أعتقد أن staticCache الإجابات السلبية (عند عدم وجود ملف) ، لذلك لا يساعد إذا قمت بوضع staticCache فوق router دون staticCache إلى مسار.

كما هو الحال مع جميع الأسئلة المتعلقة بالأداء ، قم بقياس ومقارنة تطبيقك في العالم الحقيقي (تحت الحمل) لمعرفة أين توجد الاختناقات بالفعل.

Express 4

Express 4.0 يزيل app.router . تتم الآن معالجة جميع البرامج الوسيطة ( app.use ) app.use ( app.get et al) تمامًا بالترتيب الذي تتم إضافته به.

بعبارات أخرى:

ستتم إضافة جميع طرق التوجيه بالترتيب الذي تظهر به. يجب عدم القيام app.use(app.router) . هذا يحل المشكلة الأكثر شيوعًا مع Express.

بمعنى آخر ، app.use() خلط app.use() app[VERB]() تمامًا في الترتيب الذي يتم استدعاؤها.

app.get('/', home);
app.use('/public', require('st')(process.cwd()));
app.get('/users', users.list);
app.post('/users', users.create);

اقرأ المزيد عن التغييرات في Express 4.







express