Menu
CoddyTech

Arama Sayfası

Coddy'nin Node.js Journey'sinin Express Temelleri bölümünün bir parçası. Ders 23 / 23.

Bir arama sayfası bir formdur ve sunucu, diğer GET isteklerini yanıtladığı gibi yanıtlar.

<form action="/books" method="get">
    <input name="author">
    <button>Find</button>
</form>

Bu formu göndermek, tarayıcıyı /books?author= adresine ve ardından author adlı alana yazılanlara yönlendirir. Rota, değeri req.query içinden okur. Aramadan sonra da görünür kalması için bu sözcüğü alanın value değeri olarak yazın; ziyaretçiden geldiği için kaçışlayın.

challenge icon

Görev

Kolay

Recipe Box bir arama sayfası kazanıyor. Bir ziyaretçi bir kelime yazar ve sayfada başlığında bu kelime bulunan tarifler listelenir.

  1. server.js içinde, 404 işleyicisinin üstüne /search için eşzamansız bir rota ekle. Kelimeyi req.query.q üzerinden alır veya yoksa boş bir dize kullanır.
  2. Sayfada her zaman bir arama formu bulunur: <form action="/search" method="get">; formda q adlı bir metin alanı ve bir düğme vardır. Formu göndermek, kelimenin ardından /search?q= adresini açar.
  3. Alana aranan kelime yazılır: curry aramasından sonra alanda curry görünür. Kelime ziyaretçiden geldiği için, escapeHtml işlevinden geçirdikten sonra alanın value özniteliğine yaz.
  4. Formun altında, başlığında kelimenin geçtiği loadRecipes() içindeki her tarif için bir bağlantı listele; büyük-küçük harfleri yok say: soup ve SOUP aramalarının ikisi de Tomato Soup tarifini bulur. Her bağlantı tarifin sayfasına gider ve ana sayfadaki gibi kaçışlanmış başlığını gösterir: <a href="/recipes/1">Tomato Soup</a>.
  5. Bir kelime aranmışsa ve hiçbir başlıkta bu kelime geçmiyorsa liste yerine No recipes found metnini göster.

Dene: Run düğmesine bas ve /search adresine istek gönder: sayfada boş form görünür. Alana SOUP yaz ve düğmeye bas. Sayfada Tomato Soup listelenir ve alanda hâlâ SOUP görünür. pizza araması yap: No recipes found. fish araması yap: Fish & Chips doğru şekilde gösterilir. Ardından {"title": "Pea Soup", "tags": ["soup"]} içeriğini /api/recipes adresine POST et ve yeniden soup araması yap: Pea Soup da listede yer alır.

Kendin dene

import { escapeHtml } from './html.js';
import { dayOfYear } from './day-of-year.js';
import express from 'express';
import { randomUUID } from 'node:crypto';
import { recipes } from './data.js';
import recipesRouter, { loadRecipes } from './routes/recipes.js';
import reviewsRouter from './routes/reviews.js';

const app = express();

app.use((req, res, next) => {
    console.log(`${req.method} ${req.url}`);
    next();
});

app.use((req, res, next) => {
    res.set('X-Request-Id', randomUUID());
    next();
});

app.use(express.json());

app.use(express.static('public'));

app.get('/', (req, res) => {
    const items = recipes.map((r) => `<li><a href="/recipes/${r.id}">${escapeHtml(r.title)}</a></li>`);
    res.send(`<link rel="stylesheet" href="/style.css"><h1>Recipe Box</h1><ul>${items.join('')}</ul>`);
});

// type('text') düz metin gönderir; bu nedenle her başlık ayrı bir satırda görünür.
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.use('/api/recipes', recipesRouter);
app.use('/api/recipes/:id/reviews', reviewsRouter);

app.get('/api/today', async (req, res) => {
    const day = dayOfYear(req.query.date);
    if (day === null) {
        res.status(400).json({ error: 'Use a date like 2026-03-01' });
        return;
    }
    const recipes = await loadRecipes();
    res.json(recipes[day % recipes.length]);
});

app.get('/about', (req, res) => {
    res.send('Recipe Box collects family recipes.');
});

app.get('/menu', (req, res) => {
    res.redirect(301, '/recipes');
});

app.get('/menu/:id', (req, res) => {
    res.redirect(301, `/recipes/${req.params.id}`);
});

app.use((req, res) => {
    if (req.path.startsWith('/api/')) {
        res.status(404).json({ error: 'Not found' });
        return;
    }
    res.status(404).send('<h1>Page not found</h1><p><a href="/">Back to Recipe Box</a></p>');
});

app.use((err, req, res, next) => {
    console.error(err);
    res.status(500).json({ error: 'Something went wrong' });
});

app.listen(3000, () => {
    console.log('Recipe Box is running on port 3000');
});

Express Temelleri bölümündeki tüm dersler

Kendi başına pratik yap: Express playground