الملفات الثابتة
جزء من قسم أساسيات Express في رحلة Node.js على Coddy. الدرس 9 من 20.
لا تتغير ورقة الأنماط أو الصورة أبدًا، كما أن إنشاء مسار لكل ملف سيكون عملًا لا طائل منه.
app.use(express.static('assets'));تقدّم express.static('assets') ملفات مجلد assets بأسمائها نفسها: يستجيب assets/logo.png للطلب GET /logo.png. لا يكون اسم المجلد جزءًا من عنوان URL. يحدد Express نوع المحتوى من الامتداد: text/css للامتداد .css، وimage/png للامتداد .png. إذا لم يوجد ملف للمسار، ينتقل الطلب إلى مساراتك.
تضيف app.use دالة تُنفَّذ مع كل طلب؛ ويتناول الفصل التالي هذه الدوال. أصبح في مشروعك الآن مجلد public يحتوي على ورقة أنماط.
التحدي
سهل- قدِّم محتويات المجلد
public، بحيث يعرضGET /style.cssالملف. - اربطه من الصفحة الرئيسية باستخدام
<link rel="stylesheet" href="/style.css">.
افتح / في عرض الصفحة، ثم أرسل GET /style.css وGET /missing.css.
جرّب بنفسك
import express from 'express';
import { recipes } from './data.js';
const app = express();
const escapeHtml = (text) =>
text
.replaceAll('&', '&')
.replaceAll('<', '<')
.replaceAll('>', '>')
.replaceAll('"', '"');
app.get('/', (req, res) => {
const items = recipes.map((r) => `<li><a href="/recipes/${r.id}">${escapeHtml(r.title)}</a></li>`);
res.send(`<h1>Recipe Box</h1><ul>${items.join('')}</ul>`);
});
// ترسل type('text') نصًا عاديًا، لذا يظهر كل عنوان في سطر منفصل.
app.get('/recipes', (req, res) => {
const { tag } = req.query;
const list = tag ? recipes.filter((recipe) => recipe.tags.includes(tag)) : recipes;
res.type('text').send(list.map((recipe) => recipe.title).join('\n'));
});
app.get('/recipes/:id', (req, res) => {
const recipe = recipes.find((r) => r.id === Number(req.params.id));
if (!recipe) {
res.status(404).send('No such recipe');
return;
}
res.send(recipe.title);
});
app.get('/api/recipes', (req, res) => {
res.json(recipes);
});
app.get('/api/recipes/:id', (req, res) => {
const recipe = recipes.find((r) => r.id === Number(req.params.id));
if (!recipe) {
res.status(404).json({ error: 'No such recipe' });
return;
}
res.json(recipe);
});
app.get('/about', (req, res) => {
res.send('Recipe Box collects family recipes.');
});
app.listen(3000, () => {
console.log('Recipe Box is running on port 3000');
});