Node.js
даJavaScript
Язык разрабатывался на основе, поэтому фронтенд-разработчикам надо родиться с небольшим. Обычно мы будем использовать его, чтобы сделатьCLI工具
илиWeb服务器
,ДелатьWeb服务器
Есть также много зрелых фреймворков, таких какExpress
а такжеKoa
. ноExpress
а такжеKoa
отличноNode.js
РоднойAPI
инкапсуляция, так по сути без фреймворка, только роднойAPI
Мы также можем написатьWeb服务器
публично заявить. В этой статье речь пойдет не об использовании фреймворка, а только о нативномAPI
как написать одинWeb服务器
. Потому что в моем плане я напишу позжеExpress
а такжеKoa
Парсинг исходного кода, все они реализованы с помощью нативного API. Так что эта статья на самом деле является предварительным знанием этих двух анализов исходного кода, которые могут помочь нам лучше понятьExpress
а такжеKoa
Смысл и исходный код этого фреймворка.В этой статье только объясняется, как использовать нативный API, код уродлив, пожалуйста, не имитируйте его в реальной работе!
Пример исполняемого кода из этой статьи был загружен на GitHub, вы можете снять его и поиграть:GitHub.com/Денис — см....
Hello World
Чтобы построить простойWeb服务器
, используя роднойhttp
модуля достаточно, простойHello World
Для программы достаточно нескольких строк кода:
const http = require('http')
const port = 3000
const server = http.createServer((req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'text/plain')
res.end('Hello World')
})
server.listen(port, () => {
console.log(`Server is running on http://127.0.0.1:${port}/`)
})
Этот пример очень прост, непосредственно используйтеhttp.createServer
Создал сервер, этот сервер не имеет логики, просто возвращается при доступеHello World
. После создания сервера используйтеserver.listen
действующий3000
Просто порт.
Этот пример действительно прост, но он, кажется, выводитHello World
Кроме того, он ничего не умеет, это далеко не то, чем мы обычно пользуемсяWeb服务器
До этого еще далеко, в основном из-за следующих частей:
- не поддерживается
HTTP
глаголы, такие какGET
,POST
Ждать- Маршрутизация не поддерживается
- Хостинг без статического ресурса
- Данные не могут быть сохранены
Первые три пункта являются однимWeb服务器
Необходимые базовые функции, нужна ли четвертая точка, зависит от ситуации, в конце концов, есть многоNode
изWeb服务器
Так же, как промежуточный слой, это все еще различные микросервисы, которые действительно имеют дело с базой данных для сохраняемости, но мы также должны знать, как делать сохраняемость.
Итак, давайте напишем действительно полезныйWeb服务器
, то есть восполнить недостающие точки спереди.
Обработка маршрутизации и HTTP-команд
тот, что перед намиHello World
Это не совсем бесполезно, потому что местоположение кода все еще должно быть вhttp.createServer
Внутри добавляем функцию роутинга внутри. Чтобы отличить его от следующих статических ресурсов, все запросы нашего API начинаются с/api
начало. Сопоставить маршруты несложно, проще всего напрямую использоватьif
Условное суждение подойдет. Чтобы получить адрес запроса, нам нужно использоватьurl
модуль для разбора переданного адреса. а такжеHttp
глаголы могут использоваться напрямуюreq.method
получать. такhttp.createServer
Трансформация выглядит следующим образом:
const url = require('url');
const server = http.createServer((req, res) => {
// 获取url的各个部分
// url.parse可以将req.url解析成一个对象
// 里面包含有pathname和querystring等
const urlObject = url.parse(req.url);
const { pathname } = urlObject;
// api开头的是API请求
if (pathname.startsWith('/api')) {
// 再判断路由
if (pathname === '/api/users') {
// 获取HTTP动词
const method = req.method;
if (method === 'GET') {
// 写一个假数据
const resData = [
{
id: 1,
name: '小明',
age: 18
},
{
id: 2,
name: '小红',
age: 19
}
];
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify(resData));
return;
}
}
}
});
теперь мы посещаем/api/users
Вы можете получить список пользователей:
Поддержка статических файлов
сказано вышеAPI
запрос/api
В начале, то есть файлы, которые не начинаются с этого, можно рассматривать как статические файлы, и разные файлы имеют разныеContent-Type
В этом примере мы поддерживаем только один..jpg
Бар. На самом деле это для насif (pathname.startsWith('/api'))
добавить одинelse
Просто сделай это. Для возврата статических файлов требуется:
- использовать
fs
Модуль читает файл.- Возвращает файл, если он отличается в зависимости от разных типов файлов.
Content-Type
.
так что мыelse
Это выглядит так:
// ... 省略前后代码 ...
else {
// 使用path模块获取文件后缀名
const extName = path.extname(pathname);
if (extName === '.jpg') {
// 使用fs模块读取文件
fs.readFile(pathname, (err, data) => {
res.setHeader('Content-Type', 'image/jpeg');
res.write(data);
res.end();
})
}
}
Затем мы помещаем изображение в каталог того же уровня, чтобы попробовать:
сохранение данных
Существует несколько способов сохранения данных, как правило, они хранятся в базе данных, а в некоторых случаях и в файлах. Хранить базу хлопотнее, да и создавать и подключаться к базе тоже надо, тут у нас плохо.demo
, здесь мы демонстрируем пример сохранения файла. в общемPOST
Запрос используется для сохранения новых данных, мы добавляем базу передPOST /api/users
Чтобы добавить новый фрагмент данных, просто добавьтеif (method === 'GET')
добавить один послеPOST
Суд сделает:
// ... 省略其他代码 ...
else if (method === 'POST') {
// 注意数据传过来可能有多个chunk
// 我们需要拼接这些chunk
let postData = '';
req.on('data', chunk => {
postData = postData + chunk;
})
req.on('end', () => {
// 数据传完后往db.txt插入内容
fs.appendFile(path.join(__dirname, 'db.txt'), postData, () => {
res.end(postData); // 数据写完后将数据再次返回
});
})
}
Затем мы тестируем этоAPI
:
Зайди и посмотри, написано ли в файле:
Суммировать
Здесь мы выполнили основную функциюweb服务器
, код не сложный, но чтобы помочь нам понятьNode web服务器
Принцип очень полезный. Но с приведенным выше кодом все еще есть большая проблема:код уродлив! Весь код написан кучей, иHTTP动词
и сопоставление маршрутов все используетif
Условное суждение, если есть сотниAPI
, с дюжиной или около того глаголов, и код — это катастрофа! Поэтому мы должны поставить路由处理
,HTTP动词
,静态文件
,数据持久化
Все эти функции извлекаются, что делает все приложение более элегантным и масштабируемым. ЭтоExpress
а такжеKoa
О значении этих фреймворков мы поговорим в следующей статьеExpress
Исходный код, чтобы увидеть, как он решает эту проблему, нажмите на него и не теряйтесь~
Пример исполняемого кода из этой статьи был загружен на GitHub, вы можете снять его и поиграть:GitHub.com/Денис — см....
В конце статьи спасибо, что потратили свое драгоценное время на чтение этой статьи. Если эта статья немного поможет вам или вдохновит, пожалуйста, не скупитесь на лайки и звезды GitHub. Ваша поддержка является движущей силой для автор продолжать творить.
Добро пожаловать, чтобы обратить внимание на мой общедоступный номербольшой фронт атакиПолучите высококачественные оригиналы впервые~
Цикл статей "Передовые передовые знания":nuggets.capable/post/684490…
Адрес GitHub с исходным кодом из серии статей «Advanced Front-end Knowledge»:GitHub.com/Денис — см....