Quick Start
配置环境和依赖
- 下载安装Nodejs
- $node -v 查看是否已经安装
- nodejs安装完自带npm(Nodejs平台的默认包管理工具)
- 安装 Yarn
# 通过 npm 可以全局或本地安装依赖包,当本地安装时 npm 会根据 package.json 安装最新的依赖包,同时自动生成并更新 package-lock.json 文件,这就引发了一个问题:如果一个依赖包在 package.json 标记版本范围内发布了有问题的新版本,那么我们自己的项目也会跟着出问题。 # 相比 npm,yarn 会严格按照自动生成的 yarn.lock 本地安装依赖包,只有增删依赖或者 package.json 标记版本发生不可兼容的变化时才会更新 yarn.lock,这就彻底杜绝了上述 npm 的问题。考虑到企业级 Web 服务器对稳定性的要求,yarn 是必要的。 $npm i -g yarn
- 下载第三方模块
# 新建一个文件夹,并在当前文件夹内创建一个js文件,比如app.js $npm init # 安装package.json文件 $npm install express --save # 安装express库
- 安装Docker
做一个 Web 服务器会有两种部署选择,要么是传统的包部署,要么是容器镜像部署 后者较前者在编排上更方便,结合 Kubernetes 可以做到很好的伸缩,是当前发展的趋势
创建一个静态资源服务器
初始化工程
准备好了环境就可以开始编码了,先新建工程根目录,然后进入并初始化package.json
与目录结构
$ mkdir node # 新建工程根目录
$ cd node # 进入工程根目录
$ yarn init -y # 初始化 package.json
yarn init v1.22.4
success Saved package.json
$ mkdir src # 新建 src 目录存放核心逻辑
$ mkdir public # 新建 public 目录存放静态资源
$ tree -L 1 # 展示当前目录内容结构
.
├── package.json
├── public
└── src
Express
Express是Node.js服务端基础框架。发布于2010年,凭借出色的中间件机制在开源社区积累了大量的成熟模块,现在是OpenJS基金会At-Large级别项目。Express模块的贡献者热心于维护与更新,在全面的考量下Express是更稳健的选择。
几个常用模块:
模块名称 | 功能简介 | Star | Contributers | Used by | 最近提交时间 |
---|---|---|---|---|---|
passport | 认证登录 | 17.7k | 33 | 385k | 2020-06-10 |
connect-redis | 会话存储 | 2.3k | 51 | 26.3k | 2020-07-10 |
helmet | 网络安全 | 7.2k | 25 | 136.4k | 2020-07-11 |
在工程根目录执行以下命令安装Express
$ yarn add express # 本地安装 Express
# ...
info Direct dependencies
└─ express@4.17.1
# ...
$ tree -L 1 # 展示当前目录内容结构
.
├── node_modules
├── package.json
├── public
├── src
└── yarn.lock
静态服务
现在可以开始写应用逻辑了,先做一个静态资源服务器,以public
目录为静态资源目录:
// src/server.js
const express = require('express');
const { resolve } = require('path');
const { promisify } = require('util');
const server = express();
const port = parseInt(process.env.PORT || '9000');
const publicDir = resolve('public');
async function bootstrap() {
server.use(express.static(publicDir));
await promisify(server.listen.bind(server, port))();
console.log(`> Started on port ${port}`);
}
bootstrap();
<!-- public/index.html -->
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1>It works!</h1>
</body>
</html>
$ tree -L 2 -I node_modules # 展示除了node_modules之外的目录内容结构
.
├── package.json
├── public
│ └── index.html
├── src
│ └── server.js
└── yarn.lock
逻辑写好之后在package.json中设置启动脚本:
{
"name": "00-static",
"version": "1.0.0",
- "main": "index.js",
+ "scripts": {
+ "start": "node src/server.js"
+ },
"license": "MIT",
"dependencies": {
"express": "^4.17.1"
}
}
//1. 加载http模块
var http = require('http');
//2. 创建http服务器
// 参数: 请求的回调, 当有人访问服务器的时候,就会自动调用回调函数
var server = http.createServer(function (request, response) {
console.log('有人访问了服务器')
//回调数据
response.write('Hello, My Love')
response.end()
})
//3. 绑定端口
server.listen(3000, '127.0.0.1')
//4. 执行
console.log('执行了3000')
// http://localhost:5000
$node app.js # 运行服务器
Create Server by Express
Use Express Framework
1. 引入express模块
2. 创建express服务器
3. get, post请求中:
- 参数一: 请求根路径
- 若传'/', 则url为: http://192.168.0.0:3030
- 若传'/home', 则url为: http://192.168.0.0:3030/home
- 参数二: 请求数据的回调函数
4. 监听端口: 默认url为当前电脑的IP地址
/* express的服务器 */
//1. 导入express
var express = require('express')
//2. 创建express服务器
var server = express()
//3. 访问服务器(get或者post)
//参数一: 请求根路径
//3.1 get请求
server.get('/', function (request, response) {
// console.log(request)
response.send('get请求成功')
})
//3.2 post请求
server.post('/', function (request, response) {
response.send('post请求成功')
})
//4. 绑定端口
server.listen(5000)
console.log('启动5000')
// http://localhost:5000
路由
1. 路由: 针对不同的URL有不同的处理方式
2. 添加url路径: 根据不同路径,显示不同内容
3. 路由句柄(索引): 执行完一个函数,再执行下一个,因为有时候处理一个请求,需要做很多其他事情,写在一起业务逻辑不好分开
4. 函数一定要添加next参数,一定要调用next(),才会进行下面操作,代码使一行一行执行
//3.1 get请求
server.get('/', function (request, response, next) {
// console.log(request)
console.log('从据库获取数据') // 显示在terminal里
next()
}, function (request, response) {
response.send('get请求成功') // 显示在网页上
})
// http://localhost:5000
中间件
- 优化代码,使代码清晰可读
- 原理: 发送一个请求给服务器的时候,会被中间件拦截,先由中间件处理,每个中间件都有一个回调函数作为参数,拦截到参数,就会自动执行回调函数。
- 注意:有中间件use,会先执行中间件的回调函数,然后才会调用get或者post的回调函数,也就是当监听到请求,先执行中间件,才会到get、post请求。
- use是express注册中间件的方法
//3. 创建中间件:use
//截取请求, 拦截回调
server.use('/', function (request, response, next) {
console.log('执行中间件')
// console.log('获取数据库数据')
console.log(request.query.page)
next()
})
//4. 访问服务器(get或者post)
//参数一: 请求根路径
//4.1 get请求
server.get('/home', function (request, response) {
// console.log(request)
response.send('get参数请求成功')
})
// http://localhost:5000/home
get请求参数
- request.query会把请求参数包装成字典对象,直接通过点就能获取参数
//4. 访问服务器(get或者post)
//参数一: 请求根路径
//4.1 get请求
server.get('/home', function (request, response) {
// console.log(request)
console.log(request.query.page) // 12
response.send('get参数请求成功')
})
// http://localhost:5000/home?page=12
post请求参数
先看一下request的部分参数
headers:
{
//请求头
host: 'http://localhost:5000/home',
//保持长连接
connection: 'keep-alive',
'cache-control': 'max-age=0',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36',
'upgrade-insecure-requests': '1',
//可接受的数据解析方式
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'accept-encoding': 'gzip, deflate',
'accept-language': 'zh-CN,zh;q=0.9',
'if-none-match': 'W/"15-H7HlVCzzVfmRL56LAnLfNUaMM+8"'
}
- 使用http发送请求,需要设置content-type字段
- content-type字段
- application/x-www-form-urlencoded(普通请求,默认一般使用这种)
- application/json(带有json格式的参数,需要使用这个,比如参数是字典或者数组)
- multipart/form-data(传输文件,文件上传使用这个)
- Node.js需要使用body-parser模块,解析post请求参数
- 可以采用中间件的方式解析post请求参数
- 注意bodyParser.urlencoded参数是一个字典,需要添加{}包装
- extends必传参数,是否展开