node.js入门笔记
JavaScript使用时存在两大问题,文件依赖和命名冲突
两者相等,指向同一个引用地址,如果module.exports和exports都进行了修改,最终以module.exports为准
node运行环境提供的API,因为这些Api都是以模块化方式进行开发的,所以又称node运行环境的api为系统模块
node中的回调函数都是错误函数,第一个参数为报错信息,第二个时数据,如果没有错,第一个参数为null
fs.readFile(‘文件路径/文件名称’,[编码格式],callback)
// 导入文件模块
const fs = require('fs');
// node,读写文件也有同步和异步的接口
fs.readFile('hello.txt', {
flag: 'r',
encoding: "utf-8"
},(err,data)=>{
if(err){
console.log(err)
}else{
console.log(data)
}
})
console.log(content);
fs.writeFile(“文件按路径/文件名称”,‘数据’,callback)
// 导入文件模块
const fs = require('fs');
fs.writeFile('./demo.txt','即将写入的内容',err=>{
if(err!=null){
console.log(err);
return;
}
console.log("文件内容写入成功")
})
path.join(“路径”,“路径”,…)
const path = require("path")
const finalPath = path.join("public",'uploads','avatar')
console.log(finalPath)//public\uploads\avatar
// 拼接成绝对路径
const path = require('path')
let info2 = path.join(__dirname,'sxt','qianduan')
// 创建网站服务器模块
const http = require("http")
// app对象就是网站服务器对象
const app = http.createServer()
// 当客户端有请求来的时候
app.on("request", (req, res) => {
//req为请求的,res为响应
// 根据请求执行对应的事件
})
// 监听端口
app.listen(3000)
console.log("服务器端口已启动,使用localhost:3000访问");
const url = require('url')
//url.parse(要解析的url地址,true(将查询参数(query)解析成对象形式))
let {query,pathname} = url.parse(req.url,true)
const querystring = require("querystring")
app.on("request", (req, res) => {
// post 参数是通过事件的方式接受的
//data 当请求参数传递的时候触发data事件
//end 当参数参数完成时触发end事件
let postParams = ''
req.on("data",params=>{
// 将获取到的params参数拼接在一起
postParams += params
})
req.on('end',()=>{
let queryPa = querystring.parse(postParams)
console.log(querystring.parse(postParams));
console.log(queryPa.username);
})
res.end('ok')
})
npm(node package manager):node 的第三方模块管理工具
全局安装和本地安装
nodemon是一个命令行工具,用于辅助项目开发
在node。js中,每次修改文件都要在命令行工具中重新执行,很繁琐
使用步骤
nrm: npm下载地址切换工具
npm默认的下载地址在国外,国内下载速度慢
使用步骤
基于node平台开发的前端构建工具
将机械化操作编写成任务,想要执行机械化操作时执行一个命令行命令任务就能自动执行
基本使用
npm install gulp-cli -g
终端执行gulp 任务名(task) 执行任务
// 不做异步处理或加dom,会报错The following tasks did not complete: first Did you forget to signal async completion?
// 引用gulp模块
const gulp = require("gulp")
// 使用gulp.task建立任务
// 1. 任务的名称
// 2. 任务的回调函数
// gulp.task("first", async() => {
// console.log("第一个gulp任务执行了");
// // 1. 使用gulp.src 获取要处理的文件
// await gulp.src("./src/css/index.css")
// .pipe(gulp.dest('dist/css'))
// })
//gulp 4.0 的任务函数中,如果任务是同步的,需要使用 done 回调。这样做是为了让 gulp 知道你的任务何时完成。
gulp.task("first", (done) => {
console.log("第一个gulp任务执行了");
// 1. 使用gulp.src 获取要处理的文件
gulp.src("./src/css/index.css")
.pipe(gulp.dest('dist/css'))
done()
})
插件网址
gulp-file-include使用方法:
1.文件过多,将项目整体拷贝给别人,传输速度太慢
2. 复杂的模块依赖关系需要被记录,确保模块的版本和当前保持一直
项目根目录npm init -y初始化package.json文件夹
下载的依赖都会记录在dependencies中,只需执行npm install就能把需要的依赖下载好
npm install 所有依赖都下载好
npm install product 只下载项目依赖
// package.json里的
"dependencies": {
"formidable": "^1.2.2",
"mime": "^2.4.6"
}
// package.json
//scripts别名 "build"命令替换原来的nodemon app.js命令。npm run build执行
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build","nodemon app.js"
},
"devDependencies": {
"gulp": "^4.0.2"
}
require(’./find.js’)
require(’./find’)
require(‘find’)
URL组成
传输协议:服务器ip或域名:端口/资源所在位置表示,一般端口默认8080会省略
http://www.itcast.cn/index.html
http: 超文本传输协议,提供了一种发布和接收html页面方法
// 创建网站服务器模块
const http = require("http")
// app对象就是网站服务器对象
const app = http.createServer()
// 当客户端有请求来的时候
app.on("request",(req,res)=>{
//req为请求的,res为响应
res.end('hello user
')
})
// 监听端口
app.listen(3000)
console.log("服务器端口已启动,使用localhost:3000访问");
超文本传输协议,规定如何从网站服务器传输文本到本地浏览器,基于客户端服务器架构工作,是客户端(用户)和服务器端(网站)请求和应答标准
在HTTP请求和响应的过程中传递的数据块就叫报文,包括要传送的数据和一些附加信息,并且要遵守好规定的格式
客户端->服务器端 请求报文(请求方式(post),请求地址)
服务器端-> 客户端 响应报文(内容类型(text/html),内容长度)
app.on("request", (req, res) => {
// 获取请求方式,console.log(req.method)
// 获取请求地址
req.url
// 获取请求报文
req.headers
}
if(req.url=='/index'||req.url=="/"){
res.end("welcome to homepage欢迎来到首页
")
}
else if(req.url=='/list'){
res.end("welcome to list")
}
else{
res.end("no find")
}
if(req.method=='GET'){
res.end("GET请求")
}else if(req.method==='POST')
{
res.end("post请求")
}
}
http.on("request",(req,res)=>{
res.writeHead(200,{
// 默认content-type ,纯文本
// "content-type":'text/plain'
// 设置为text/html就能看到返回的html代码效果了
"content-type":'text/html;charset=utf8'
})
if(req.url=='/index'||req.url=="/"){
res.end("welcome to homepage欢迎来到首页
")
}
}
客户端向服务器发送请求携带的信息。
GET请求参数
POST请求参数
// 创建网站服务器模块
const http = require("http")
//处理请求参数模块 querystring,querystring.parse解析成对象形式
const querystring = require("querystring")
// app对象就是网站服务器对象
const app = http.createServer()
// 当客户端有请求来的时候
app.on("request", (req, res) => {
// post 参数是通过事件的方式接受的
//data 当请求参数传递的时候触发data事件
//end 当参数参数完成时触发end事件
let postParams = ''
req.on("data",params=>{
// 将获取到的params参数拼接在一起
postParams += params
})
req.on('end',()=>{
let queryPa = querystring.parse(postParams)
console.log(querystring.parse(postParams));
console.log(queryPa.username);
})
res.end('ok')
})
// 监听端口
app.listen(3000)
console.log("服务器端口已启动,使用localhost:3000访问");
路由是由指客户端请求地址与服务器程序代码的对应关系,即请求什么响应什么
const http = require("http")
const url = require("url")
const app = http.createServer()
app.on("request", (req, res) => {
res.writeHead(200, {
"content-type": 'text/html;charset=utf-8'
})
const method = req.method.toLowerCase()
const pathname = url.parse(req.url).pathname
if (method == 'get') {
if (pathname == '/' || pathname=='/index') {
res.end("欢迎来到首页")
} else if (pathname == '/list') {
res.end("欢迎来到列表页")
} else {
res.end("404网页已丢失")
}
}
})
app.listen(3000)
console.log("服务开启,访问http://localhost:3000");
服务器端不需要处理,可以直接响应给客户端的资源就是静态资源,如:CSS,JavaScript,image文件
相同的请求地址不统的响应资源,这种资源就是动态资源
http://www.itcast.cn/article?id=1
http://www.itcast.cn/article?id=2
mime.getType(path)
const http = require("http")
const url = require("url")
const path = require("path")
const fs = require("fs")
const mime = require("mime")
const app = http.createServer()
app.on("request",(req,res)=>{
let pathname = url.parse(req.url).pathname
pathname = pathname=="/"?'/3d.html':pathname
const relPath = path.join(__dirname,"public",pathname)
// 获取资源类型
const type = mime.getType(relPath)
// console.log(relPath);
fs.readFile(relPath,(err,data)=>{
if(err!=null){
res.writeHead("404",{
"content-type":"text/html;charset=utf-8"
})
res.end("访问失效")
}
else{
res.writeHead("200",{
"content-type":type
})
res.end(data)
}
})
})
app.listen(3000)
console.log("服务器已启动");
同步api:只有当前api执行完成,才能继续下一个api
异步api: 当前api的执行不会阻碍后续代码的执行
同步API可以从返回值拿到api结果,异步不行
// 同步
function sum(n1,n2){
return n1+n2
}
const result = sum(10,20) // 30
function getMsg(){
setTimeout(function(){
return{
msg:'hello node.js'
}
},2000)
// return undefined 函数默认会有个返回undefined
}
const msg = getMsg()
// 执行完异步函数时,msg已经输出的
console.log(msg); //undefined
自己定义函数让别人调用
// 自己定义函数让别人调用
function getData(callback){}
//getdata函数调用
getData(()=>{})
同步api从上到下一次执行,前面的代码会阻塞后面的代码执行
for(var i=0;i<10000;i++){
console.log(i)
}
console.log("for后面的代码")
// 会先执行for循环在输出
异步api不会等待api执行完成后再向下执行代码
console.log("代码开始执行")
setTimeout(()=>{console.log("2秒后执行")},2000)
setTimeout(()=>{console.log("0秒后执行")},0)
console.log("代码结束执行")
// 结果:代码开始执行,代码结束执行,0秒后执行,2秒后执行
先执行同步代码,遇到异步代码时先放置回调函数队列,同步代码执行完毕后,根据异步代码执行区去找到对应的回调函数队列里的异步函数,将其执行
fs.readFile('./demo.txt',(err,result)=>{})
var server = http.creteServer()
server.on('request',(req,res)=>{})
let promise = new Promise((resolve,reject)=>{
setTimeout(()=>{
if(true){
resolve("成功了")
}
else{
reject("失败了")
}
},2000)
})
promise.then(result=>console.log(result))
.cath(error=>console.log(error))
async function fn(){
// async 会把函数编程异步函数,返回promise对象,return为原来的resolve方法
return "成功"
}
fn().then((result)=>{
console.log(result);
})
async function f2(){
// throw为原来的reject方法
throw "错误"
}
f2().then((result)=>{
console.log(result);//不执行
}).catch(err=>{
console.log(err);//返回了错误
})
相当于封装了一个new Promise()方法
let fs = require("fs")
let promisify = require("util").promisify
// 改造现有异步函数api让其返回promise对象 从而支持异步函数语法
let readFile = promisify(fs.readFile)
async function run(){
let r1 = await readFile("1.txt","utf-8")
let r2 = await readFile(r1+".txt","utf-8")
let r3 = await readFile(r2+".txt","utf-8")
}
run()
在一个数据库软件中可以包含多个数据库,在每个数据仓库中可以包含多个数据集合,每个数据集中中可以包含多条文档(具体数据)
术语 | 解释说明 |
---|---|
database | 数据库,mongoDB数据库软件可以建立多个数据库 |
collection | 集合,一组数据的集合,可以理解为JavaScript中的数组 |
document | 文档,一条具体的数据,可以理解为JavaScript中的对象 |
field | 字段,文档中的属性名称,可以理解为JavaScript中的对象属性 |
使用mongoDB下载好mongodb后,进入bin文件,执行命令行 mongod --dbpath E:\web前端总学习\Node学习\软件\datapack 开启mongod,就可以使用图形化工具连接数据库了
// 没有playground数据库会自动创建
const mongoose = require("mongoose")
mongoose.connect("mongodb://localhost/playground",{useNewUrlParser: true,useUnifiedTopology: true})
.then(()=>{
console.log('数据库连接成功');
})
.catch(()=>{
console.log('连接失败');
})
创建集合分为两步,一是对集合设定规则,二是创建集合,创建mongoose.Schema构造函数的实例即可创建集合
创建文档实际就是插入数据
分两步:
let mongoose = require("mongoose")
mongoose.connect("mongodb://localhost/playground",{useNewUrlParser: true,useUnifiedTopology: true})
.then(()=>{
console.log('数据库连接成功');
})
.catch(()=>{
console.log('连接失败');
})
// 设定集合规则
const courseSchema = new mongoose.Schema({
name:String,
author:String,
isPublished:Boolean
})
// 创建集合并应用规则,接收的是构造函数
// 第一个参数为集合名称,第二参数为集合规则,在compass中会集合名称会自动加上s和变小写
const Course = mongoose.model("Course",courseSchema) //courses
// 创建文档
const course = new Course({
name:'ljx2',
author:'ali',
isPublished:true
})
// 将文档插入到数据库
course.save()
向集合中插入数据的第二种方法
const Course = mongoose.model("Course",courseSchema)
Course.create({name:'ljx3',author:'第二种方法',isPublished:true},(err,data)=>{
console.log(err);
console.log(data);
})
Course.create({name:'ljx3',author:'第二种方法',isPublished:true})
.then(data=>console.log(data))
.catch(err=>console.log(err))
mongoimport -d 数据库名称 -c 集合名称 --file 要导入的文件
导入数组json时
使用mongoimport -d 数据库名称 -c 集合名称 --jsonArray 要导入的文件
find()根据条件查找文档(条件为空则查找所有文档)
Course.find().then(result=>{console.log(result)})
// 查询用户集合中的所有文档
Course.find().then(result=>{console.log(result);})
// 根据条件查询
Course.find({name:"ljx"}).then(result=>{console.log(result);})
//返回文档(数组的形式)
[
{
_id: 5f9e95da33c7093398444d30,
name: 'ljx',
author: 'ali',
isPublished: true,
__v: 0
}
]
findOne() 返回一个文档
//根据条件查询文档
Course.findOne({name:"ljx"}).then(result=>{console.log(result);})
// 返回文档
{
_id: 5f9e95da33c7093398444d30,
name: 'ljx',
author: 'ali',
isPublished: true,
__v: 0
}
// 查询用户集合中的所有文档
test.find().then(result=>{
console.log(result);})
// 根据大小与查询
test.find({
age:{
$gt:15,$lt:20}}).then(result=>console.log(result))
// 匹配包含
test.find({
hobbies:{
$in:["足球"]}}).then(result=>console.log(result))
// 需要查询的字段
test.find().select('name age -_id').then(result=>console.log(result))
// 排序,根据年龄升序排序,在字段名前加-降序排序
test.find().sort('-age').then(result=>console.log(result))
// skip(n)跳过n条数据,limit限制查询数量(分页的时候会用到)
test.find().skip(2).limit(3).then(result=>console.log(result))
findOneAndDelete()
test.findOneAndDelete({name:'ljx2'}).then(result=>{console.log(result);})
deleteMany()
test.deleteMany({hobbies:{$in:['排球']}}).then(result=>console.log(result))
// 更新单个文档
// test.updateOne({查询条件},{要修改的值})
// test.updateOne({name:'ljx6'},{name:"梁非凡"}).then(result=>console.log(result))
// 更新多个文档
// test.updataMany({},{})
test.updateMany({age:{$gt:10}},{age:100}).then(result=>console.log(result))
在创建集合规则时,可以设置当前字段的验证规则,验证失败则输入插入失败
let mongoose = require("mongoose")
mongoose.connect("mongodb://localhost/playground", {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
console.log('数据库连接成功');
})
.catch(() => {
console.log('连接失败');
})
// 设定集合规则
const postScheme = new mongoose.Schema({
title: {
type: String,
required: [true, '请输入标题'],
minlength: [2, "最小长度不能超过2"],
maxlength: [6, "最大长度不能超过6"],
// 去除空格
trim: true
},
age: {
type: Number,
// 最小的值
min: 18,
// 最大的值
max: [100, "最大年龄不能超过100"]
},
publishDate: {
type: Date,
// 设置默认值为当前时间
default: Date.now
},
category: {
type: String,
// 枚举,列举出当前字段可以拥有的值
enum: {
values: ['html', 'css', 'javascript', 'node.js'],
//返回错误的信息
message: '分类名称不可用'
}
},
// 自定义验证规则
author: {
type: String,
validate: {
validator: v => {
// 返回布尔值
// true验证成功
// false验证失败
// v 要验证的值
return v && v.length > 4
},
message: '传入的值不符合验证规则'
}
}
})
const post = mongoose.model("Post", postScheme)
post.create({
title: ' aaaaa ',
age: 99,
category: 'css',
author: '吾无异于曹贼'
}).then(result => {
console.log(result);
})
通过不同集合的数据之间是有关系的,例如文章信息何用户信息存储在不同集合中,但文章是某个用户发布的,要查询文章的所有信息包括发布用户,需要用到集合关联
const mongoose = require("mongoose")
mongoose.connect("mongodb://localhost/playground", {
useNewUrlParser: true,
useUnifiedTopology: true
}).then(() => {
console.log('数据库连接成功');
})
.catch(() => {
console.log('连接失败');
})
// 用户规则
const userSchema = new mongoose.Schema({
name:{
type:String,
required:[true,"请输入名字"]
},
age:{
type:Number
}
})
// 文章规则
const postSchema = new mongoose.Schema({
title:{
type:String
},
author:{
type:mongoose.Schema.Types.ObjectId,
ref:'User'
}
})
// 用户集合
const user = mongoose.model('User',userSchema)
// 文章集合
const Post = mongoose.model("Post",postSchema)
// 创建用户
user.create({name:'ljx',age:'18'}).then(result=>console.log(result))
// 创建文章
Post.create({title:'发布的文章题目',author:'5f9f959b8ee81514206ea593'}).then(result=>console.log(result))
// Post.find().then(result=>console.log(result))
// 联合查询
Post.find().populate('author').then(result=>console.log(result))
模板引擎是第三方模块。
让开发者更加友好地拼接字符串,是项目代码更加清晰,更加易于维护
标准语法:{ {数据}}
原始语法:<%=数据%>
将某项数据输出在模板中,标准语法和原始语法如下:
如果数据中携带html标签,默认模板引擎不会解析标签,会将其转义后输出
标准语法{ {if 条件 }}内容{ {else if 条件}}内容{ {else}}内容
{ {/if}}
原始语法<%if(条件){%>内容
<%}else if(条件){%>内容
<%}>else {%>内容
<%}%>
{
{if age > 18}}
年龄大于18
{
{else if age < 15 }}年龄小于15
{
{else}}
年龄不符合要求
{
{/if}}
// 原始语法
<% if(age>18){%>
年龄大于18
<%} else if(age<15) {%>年龄小于15
<%} else {%>年龄不符合要求
<%}%>
{
{each user}}
- {
{$index}}
- {
{$value.name}}
- {
{$value.age}}
- {
{$value.sex}}
{
{/each}}
<%for(var i = 0;i < user.length;i++){%>
-
<%= i%>
<%= user[i].name%>
<%= user[i].age%>
<%= user[i].sex%>
<%}%>
使用子模版可以将网站的公共区块(头部,底部)抽离到单独的文件中。
{
{include './common/header.art'}}
<%include('./common/footer.art')%>
使用模板继承可以将网站html骨架抽离到单独的文件中,其他页面模块可以继承骨架文件。
公共模块 layout.art 将html骨架抽离出来,并在需要填充的位置使用{ {block ‘name’}}{ {/block}}说明
{
{block 'title'}}{
{/block}}
{
{block 'link'}}{
{/block}}
{
{block 'content'}}{
{/block}}
继承模板 05.art
extent '路径’继承模板
{ {block}}内容{ {/block}}填充模板
{
{extend './common/layout.art'}}
{
{block 'title'}}
测试标题
{
{/block}}
{
{block 'content'}}
{
{msg}}
{
{/block}}
{
{block 'link'}}
{
{/block}}
// 配置模板根目录
template.defaults.root = path.join(__dirname,"views")
// 导入模板变量
template.defaults.imports.dateFormat = dateFormat
// 配置模板默认后缀
template.defaults.extname = '.html'
const html = template(viewsPath, {
time:new Date()
})
// 没有后缀时自动默认.html后缀
const html2 = template('06',{})
console.log(html);
console.log(html2);
制作流程
功能:实现路由
使用步骤:
const getrouter = require("router")
const router = getrouter()
router.get('/add',(req,res)=>{
res.end()
}
app.on('request',(req,res)=>{
router(req,res)
})
功能:实现静态资源访问服务
步骤:
const serveStatic = require("serve-static")
// 实现静态访问服务
const serve = serveStatic(path.join(__dirname,'public'))
server.on('request',()=>{
serve(req,res)
})
server.listen(3000)
添加学生信息功能步骤分析
学生信息列表页面分析
Express是一个基于node平台的web应用开发框架,它提供了一系列的强大特性,帮助你创建各种web应用。
使用npm install express下载
中间件就是一堆方法,可以接收客户端发来的请求,可以对请求做出响应,也可以将请求继续交给下一个中间件继续处理
中间件主要由两部分构成,中间件方法以及请求处理函数
中间件方法由express提供,负责拦截请求,请求处理函数由开发人员提供,负责处理请求
如:
app.get('请求路径','处理函数') //接收并处理get请求
app.post('请求路径','处理函数') //接收并处理post请求
可以针对同一个请求设置多个中间件,对同一个请求进行多次处理.
默认情况下,请求从上到下以此匹配中间件,一旦匹配成功,终止匹配.
可以调用next方法将请求的控制权交给下一个中间件,直到遇到结束请求的中间件
app.get('./request',(req,res,next)=>{
req.name='张三';
next()
})
app.get('./request',(req,res)=>{
res.send(req.name)
})
app.use 匹配所有的请求方式,可以直接传入请求处理函数,代表接收所有的请求。
注意:app.use中间件放在其他前面
app.use((req,res,next)=>{
console.log("消息经过了use中间件");
next()
})
// 加上参数地址时,表示只有该路径会触发该中间件
app.use('/request',(req,res,next)=>{
res.send("消息经过了request")
})
const app = express()
// 网站公告,直接响应公告内容
app.use((req,res,next)=>{
res.send("网站维护中。。。请于xxx时间段再访问")
})
// 拦截未登录用户
app.use((req,res,next)=>{
let isLogin = true
if(isLogin){
next()
}else{
res.send("请登录后再访问页面")
}
})
app.get('/request',(req,res,next)=>{
res.send("欢迎来到request页")
})
// 自定义404页面,放在最后面,等上面的中间件先判断完有没有符合的
app.use((req,res,next)=>{
res.status(404).send("网页不存在")
})
程序执行的过程中,不可避免的会出现一些无法预料的错误,比如文件读取失败,数据库连接失败,错误处理中间件是一个集中处理错误的地方
当程序出现错误时,调用next()方法,将错误信息传递给next()方法,即可触发错误处理中间件
app.use((err,req,res,next)=>{
res.status(500).send(err.message)
})
// 模拟异步请求发生错误,异步api的错误都是通过回调获取的
app.get('/list',(req,res,next)=>{
fs.readFile('./2文件清单.txt','utf8',(err,result)=>{
if(err!=null){
// next带参数则作为程序错误
next(err)
}else{
res.send(result)
}
})
})
// 模拟同步请求错误
app.get('/index',(req,res)=>{
throw new Error('程序发生了未知错误')
})
app.get("/request",(req,res)=>{
res.send('正常访问')
})
// 错误中间件
app.use((err,req,res,next)=>{
res.status(500).send(err.message)
})
再node.js中,异步api的错误信息都是通过回调函数获取的,支持promise对象的异步api发生错误可以通过catch方法获取。
try catch可以捕获异步函数以及其他同步代码再执行过程中发生的错误,但是不能其他类型的api(如回调函数)发生错误
const promisify = require("util").promisify
const readFile = promisify(fs.readFile)
// 模拟异步promise对象的异步api发生错误
app.get('/list',async (req,res,next)=>{
try {
await readFile('./2文件清单.txt')
} catch (error) {
next(error)
}
})
// 错误中间件
app.use((err,req,res,next)=>{
res.status(500).send(err.message)
})
基础用法
const express = require("express")
// 创建网站服务器
const app = express()
// 创建路由对象
const home = express.Router()
// 为路由对象匹配添加路径
app.use('/home',home)
// 在home路由下创建二级路由
home.get('/index',(req,res)=>{
res.send('欢迎来到首页')
})
app.listen(3000)
console.log('服务已启动');
构建模块化路由
home.js
const express = require("express")
const home = express.Router()
home.get('/index',(req,res)=>{
res.send('欢迎来到home首页')
})
module.exports = home
admin.js
const express = require("express")
const admin = express.Router()
admin.get('/index',(req,res)=>{
res.send("欢迎来到admin主页")
})
module.exports = admin
index.js
const express = require("express")
// 创建网站服务器
const app = express()
const home = require("./route/home")
const admin = require("./route/admin")
app.use('/home',home)
app.use('/admin',admin)
app.listen(3000)
console.log('服务已启动');
Express框架使用req.query即可获取get参数,框架内部会将参数转换为对象并返回
const app = express()
app.get('/index',(req,res)=>{
res.send(req.query)
})
Express接收post请求参数需要借助第三方包 body-parser
//引入body-parser模块
const bodyParser = require("body-parser")
// 配置body-parser模块
// 拦截所有请求并调用方法处理请求参数
// extended:false 方法内部使用querystring模块处理请求参数的格式
//extended:true 方法内部使用qs处理请求参数的格式
app.use(bodyParser.urlencoded({extended:false}))
// 接收请求
app.post('/add',(req,res)=>{
// 获取post请求参数
console.log(req.body)
})
// 此时需要通过http://localhost:3000/index/123/ljx 来访问
// 前面req.query获取的参数形式是http://localhost:3000/index?id=123&&name:ljx
app.get('/find/:id/:name',(req,res)=>{
res.send(req.params) //{"id":"123","name":"ljx"}
})
通过Express.static可以方便地托管静态文件
app.use(express.static('public')
const express = require("express")
const bodyParser = require("body-parser")
const path = require("path")
const app = express()
// 静态资源访问http://localhost:3000/css/list.css
// app.use(express.static(path.join(__dirname,'public')))
//静态资源访问http://localhost:3000/static/css/list.css
app.use('/static',express.static(path.join(__dirname,'public')))
app.listen(3000)
console.log("服务已启动");
为了art-template和express框架配合使用而封装成的express-art-template
使用npm install art-template express-art-template 下载
// 当渲染后缀为art的模板时,使用expree-art-template
app.engine('art',require('expree-art-template'))
// 设置模板存放目录
app.set('views',path.join(__dirname,'views'))
// 渲染模板时 不写后缀 默认拼接art后缀
app.set('view engine','art');
app.get('/',(req,res)=>{
// 渲染模板
res.render('index')
})
const express = require('express')
const path = require("path")
const app = express()
// 1. 告诉express框架使用什么模板引擎渲染什么后缀的模板文件
// 1. 模板后缀
// 2. 使用的模板引擎
app.engine('art',require("express-art-template"))
// 2. 告诉express框架模板存放的位置 views为固定的配置名称
app.set("views",path.join(__dirname,'views'))
// 3. 告诉express框架模板的默认后缀是什么
app.set('view engine','art');
app.get('/index',(req,res)=>{
res.render('index',{
msg:'index page'
})
})
app.get('/list',(req,res)=>{
//render处理了以下内容
// 1. 拼接模板路径
// 2. 拼接模板后缀
// 3. 哪一个模板和哪一个数据进行拼接
// 4. 将拼接结果响应给客户端
res.render('list',{
msg:'list page'
})
})
app.listen(3000)
console.log("服务已启动");
将变量设置在这,所有的模板都能使用这个数据
app.locals.users = [{
name:'张三',
age:14
},{
name:'李四',
age:20
}]
index.art
{
{msg}}
{
{each users}}
- {
{$value.name}}
- {
{$value.age}}
{
{/each}}
index.js
const express = require('express')
const path = require("path")
const app = express()
// 1. 告诉express框架使用什么模板引擎渲染什么后缀的模板文件
// 1. 模板后缀
// 2. 使用的模板引擎
app.engine('art',require("express-art-template"))
// 2. 告诉express框架模板存放的位置 views为固定的配置名称
app.set("views",path.join(__dirname,'views'))
// 3. 告诉express框架模板的默认后缀是什么
app.set('view engine','art');
// 设置公共的对象
app.locals.users = [{
name:'张三',
age:14
},{
name:'李四',
age:20
}]
app.get('/index',(req,res)=>{
res.render('index',{
msg:'index page'
})
})
app.get('/list',(req,res)=>{
//render处理了以下内容
// 1. 拼接模板路径
// 2. 拼接模板后缀
// 3. 哪一个模板和哪一个数据进行拼接
// 4. 将拼接结果响应给客户端
res.render('list',{
msg:'list page'
})
})
app.listen(3000)
console.log("服务已启动");