0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

node.jsによるサーバの基本構造

Last updated at Posted at 2024-06-30

プログラム例

node.js演習用のプログラム例をいくつか覚えとして、掲載しておきます。

最も基本的なサーバプログラム

リクエストがあれば、単にコンテンツを返す例。
アロー関数とコールバック関数という概念に慣れてもらうことが必要です。

const http = require('http');

const server = http.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello, World!');
});

const PORT = 3000;
server.listen(PORT, () => {
    console.log(`Server running at http://localhost:${PORT}/`);
});

POSTメソッドの確認

POSTメソッドを確認するためのnode.jsプログラム。

const http = require('http');

const server = http.createServer((req, res) => {
    // CORSヘッダーを設定
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type');

    if (req.method === 'OPTIONS') {
        // プリフライトリクエストに対応
        res.writeHead(204);
        res.end();
        return;
    }

    if (req.method === 'POST' && req.url === '/submit') {
        let body = '';

        req.on('data', chunk => {
            body += chunk.toString();
        });

        req.on('end', () => {
            try {
                const data = JSON.parse(body);
                // サーバー側での処理
                console.log('Received JSON:', data);

                // ここにサーバー側で行いたい処理を追加
                const responseMessage = {
                    message: `Hello, ${data.name}! Your age is ${data.age}.`
                };

                res.writeHead(200, { 'Content-Type': 'application/json' });
                res.end(JSON.stringify(responseMessage));
            } catch (error) {
                res.writeHead(400, { 'Content-Type': 'text/plain' });
                res.end('Invalid JSON');
            }
        });
    } else {
        res.writeHead(404, { 'Content-Type': 'text/plain' });
        res.end('404 Not Found');
    }
});

const PORT = 3000;
server.listen(PORT, () => {
    console.log(`Server running at http://localhost:${PORT}/`);
});

以上のnode.jsプログラムにアクセスをかけるためのhtmlファイル。
それとは別に、

curl -v -H "Content-Type: application/json" -d "{\"name\": \"Taro\", \"age\": 30}" http://127.0.0.1:3000/submit

として、curlでのPOSTメソッドアクセスを確認しておくと良いです。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Submit Form</title>
</head>

<body>
    <h1>Submit Your Information</h1>
    <form id="submitForm">
        <label for="name">Name:</label>
        <input type="text" id="name" name="name" required><br><br>
        <label for="age">Age:</label>
        <input type="number" id="age" name="age" required><br><br>
        <button type="submit">Submit</button>
    </form>

    <script>
        document.getElementById('submitForm').addEventListener('submit', function (event) {
            event.preventDefault();

            const name = document.getElementById('name').value;
            const age = document.getElementById('age').value;

            const data = {
                name: name,
                age: age
            };

            fetch('http://127.0.0.1:3000/submit', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(data)
            })
                .then(response => response.json())
                .then(data => {
                    console.log('Success:', data);
                    alert(`Server Response: ${data.message}`);
                })
                .catch((error) => {
                    console.error('Error:', error);
                });
        });
    </script>
</body>

</html>

コンテンツルーティングの例

コンテンツに対するルーティングの例。
/formを指定すると、HTMLの本体にformを埋め込みます。
また、POSTメソッドに対しての応答も同一プログラム内に入れています。

const http = require('http');
const url = require('url');
const querystring = require('querystring');

const renderTemplate = (title, content) => {
    return `
        <!DOCTYPE html>
        <html>
        <head>
            <title>${title}</title>
        </head>
        <body>
            <h1>${title}</h1>
            ${content}
        </body>
        </html>
    `;
};

const server = http.createServer((req, res) => {
    const parsedUrl = url.parse(req.url, true);
    const pathname = parsedUrl.pathname;

    if (req.method === 'GET') {
        switch (pathname) {
            case '/':
                res.writeHead(200, { 'Content-Type': 'text/html' });
                res.end(renderTemplate('Home Page', 'This is the content of the home page.'));
                break;
            case '/about':
                res.writeHead(200, { 'Content-Type': 'text/html' });
                res.end(renderTemplate('About Us', 'This page contains information about us.'));
                break;
            case '/form':
                const form = `
                    <form action="/form" method="post">
                        <label for="name">Name:</label><br>
                        <input type="text" id="name" name="name"><br>
                        <label for="message">Message:</label><br>
                        <textarea id="message" name="message"></textarea><br>
                        <input type="submit" value="Submit">
                    </form>
                `;
                res.writeHead(200, { 'Content-Type': 'text/html' });
                res.end(renderTemplate('Contact Form', form));
                break;
            default:
                res.writeHead(404, { 'Content-Type': 'text/html' });
                res.end(renderTemplate('404 Not Found', 'The page you are looking for does not exist.'));
        }
    } else if (req.method === 'POST' && pathname === '/form') {
        let body = '';
        req.on('data', chunk => {
            body += chunk.toString();
        });
        req.on('end', () => {
            const postData = querystring.parse(body);
            const responseContent = `
                <p>Thank you for your message, ${postData.name}.</p>
                <p>Your message: ${postData.message}</p>
            `;
            res.writeHead(200, { 'Content-Type': 'text/html' });
            res.end(renderTemplate('Contact Form - Received', responseContent));
        });
    } else {
        res.writeHead(404, { 'Content-Type': 'text/html' });
        res.end(renderTemplate('404 Not Found', 'The page you are looking for does not exist.'));
    }
});

const PORT = 3000;
server.listen(PORT, () => {
    console.log(`Server running at http://localhost:${PORT}/`);
});

httpとhttps比較用

curl -v -kで両者のアクセスを比較しましょう。
TCPからHTTPに向けてのレイヤーで何が起こっているか確認すると良いと思います。

const http = require('http');
const https = require('https');
const fs = require('fs');

// HTTP Server
const httpServer = http.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello from HTTP!');
});

// HTTPS Server
const httpsOptions = {
    key: fs.readFileSync('my0627server.key'),
    cert: fs.readFileSync('my0627server.cert')
};

const httpsServer = https.createServer(httpsOptions, (req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello from HTTPS!');
});

// Start both servers
const HTTP_PORT = 3000;
const HTTPS_PORT = 3001;

httpServer.listen(HTTP_PORT, () => {
    console.log(`HTTP Server running at http://localhost:${HTTP_PORT}/`);
});

httpsServer.listen(HTTPS_PORT, () => {
    console.log(`HTTPS Server running at https://localhost:${HTTPS_PORT}/`);
});
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?