【Hello,前端!】用 Node.js 轻松搭建服务端| 青训营笔记

26 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第14天

作为前端程序员,如果我们需要创建自己的服务端,Node.js 是一个非常好的选择,使用我们熟悉的 JavaScript 就能搭建服务端。所以,今天就让我们来看一看 Node.js 吧。

什么是 Node.js

Node.js 于2009年发布是一个基于 Chrome V8 引擎的 JavaScript 运行环境,使用了事件驱动、非阻塞式I/O的模型。

Node.js 让 JavaScript 应用程序能够运行在服务端平台,让 JavaScript 也能开发服务端应用。

除了 Web 应用,Node.js 如今也被应用在许多其他领域,涉及桌面平台应用、移动端应用、远程控制、远程监控等等。

如何开始

在安装好 Node.js 后,我们就可以着手来编写我们的第一个 Node.js 应用了。

引入模块

在 Node.js 中,我们使用 require指令来引入 Node.js 模块:

const http = require("http")

如果我们要搭建 Web 服务器,那必须要引入的就是 HTTP 模块,正如上面的例子。

创建服务

引入 HTTP 模块后,我们就可以使用http.createServer这个方法来创建服务器了,具体使用方法如下:

const port = 8000
const http = require('http')

const server = http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'})

    res.end('Hello World')
})

server.listen(port, () => {
    console.log(`Server running at http://127.0.0.1:${port}/`)
}

运行

使用 node 命令可以执行 Node.js 代码:

node server.js

此时终端会打印我们的服务器信息:

Server running at http://127.0.0.1:800/

路由

前端的请求信息存储在请求 Url 和请求体中,服务端接受到请求后要通过路由将请求数据放到不同的代码中去执行。

因此我们的 HTTP 服务器需要一个具备路由功能的模块来对 Url 进行解析。

url 模块

在 Node.js 中提供了 url 模块,可以用来解析 url 中的路径信息。

const port = 8000
const http = require("http")
const url = require("url")

function start() {
    function onRequest(req, res) {
        var pathname = url.parse(req.url).pathname
        console.log("Request for " + pathname + " received.")
        
        res.writeHead(200, {"Content-Type": "text/plain"})
        res.write("Hello World")
        res.end()
    } 
    http.createServer(onRequest).listen(8000, () => {
        console.log(`Server running at http://127.0.0.1:${port}/`)
    })
}

exports.start = start

可以看到,我们已经可以拿到请求 Url 的路径信息,接下来只需要根据路径去执行相应的代码,我们就完成了简单的路由功能。

静态文件服务

利用路由,我们就能简单地实现一个静态文件服务:

const port = 8000
const http = require("http")
const url = require("url")
const path = require("path")
const fs = require("fs")

function start() {
    function onRequest(req, res) {
        var pathname = url.parse(req.url).pathname
        console.log("Request for " + pathname + " received.")
        
        const file = fs.createReadStream(path.resolve(__dirname, '.' + pathname))
        file.pipe(res)
    } 
    http.createServer(onRequest).listen(8000, () => {
        console.log(`Server running at http://127.0.0.1:${port}/`)
    })
}

exports.start = start

这样,我们就能将根目录下名称与 Url 路径对应的文件返回到前端页面展示。

GET 与 POST 请求

不论是开发中还是日常使用中,最常见的请求就是 GET/POST 请求了,这也是我们开发服务端必不可少的功能之一。

获取 GET 请求内容

GET 请求的数据内容是直接嵌入在路径中的,在之前我们就使用了 Url 模块来解析请求 Url 从而获取 GET 请求参数。

const port = 8000
const http = require('http')
const url = require('url')
const util = require('util')

const server = http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain; charset=utf-8'})
    query = util.inspect(url.parse(req.url, true))
    console.log(query)
    res.end(query)
})

server.listen(port, () => {
    console.log(`Server running at http://127.0.0.1:${port}/`)
})

在浏览器访问 **http://localhost:8000/user?name=admin&password=qwe123**,在终端就会输出解析出来的 GET 请求内容:

Url {
  protocol: null,
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: null,
  search: '?name=admin&password=qwe123',
  query: [Object: null prototype] { name: 'admin', password: 'qwe123' },
  pathname: '/user',
  path: '/user?name=admin&password=qwe123',
  href: '/user?name=admin&password=qwe123'
}

获取 POST 请求内容

POST 请求数据内容存储在请求体中,但是 Node.js 默认并不会解析请求体,http.ServerRequest并没有提供请求体属性,所以我们需要手动的去做请求体的解析。

const port = 8000
const http = require('http')
const querystring = require('querystring')
const util = require('util')
const server = http.createServer(function(req, res){
    var post = ''
    req.on('data', function(chunk) {
        post += chunk
    })
    
    req.on('end', function() {
        post = querystring.parse(post)
        res.end(util.inspect(post))
    })
})

server.listen(port, () => {
    console.log(`Server running at http://127.0.0.1:${port}/`)
})