node.js day1 -- day4 express框架的使用

本文介绍了Node.js的基本概念,包括如何执行JavaScript代码、文件操作(读写)、创建HTTP服务,以及模块化编程的实践。内容涵盖了核心模块如fs、http的使用,以及模块加载、HTTP服务的简单搭建和模板引擎的应用。
摘要由CSDN通过智能技术生成
## 什么是node.js

在这里插入图片描述

node.js和JavaScript不完全相同

在这里插入图片描述

执行方法

需要在终端中执行代码
读写文件
D:\study\VSCODE代码\node> node day1.js //node 后面加js文件名

//使用require方法加载核心模块
var fs = require('fs');
//读取文件node可以读取文件而浏览器不能读取js hrml css以外的文件
fs.readFile('读取文件.txt', function(error, data) {
    console.log(data.toString());
});
//第一个参数是要读文件的路径,第二个参数是回调函数
如果文件读取成功  error :null  data为文件内容
如果文件读取失败  error: 错误信息   data:undefined

写入文件:
如果输出成功 error =null 输出错误 error 就是错误信息
可以在终端文件下写入文件 第一个参数是文件地址和文件名 第二个参数是文件内容 第三个是回调函数

// 写入文件    如果输出成功  error =null   输出错误  error 就是错误信息 
// 可以在终端文件下写入文件   第一个参数是文件地址和文件名   第二个参数是文件内容    第三个是回调函数
fs.writeFile('data/写入文件.js', '我是写入的文件,又创建了一个文件夹', function(error) {
    console.log('文件写入成功');
});

简单的HTTP服务

服务器要干嘛
在这里插入图片描述

// 创建一个服务器    提供对数据的服务
//http是一个核心模块
//加载核心模块
var http = require('http');
// 返回一个服务器实例
var server = http.createServer();
// 当客户端收到请求就会自动触发服务器的request请求然后执行第二个参数
server.on('request', function() {
    console.log('收到客户端的请求');
});
// 绑定端口号启动服务器
server.listen(3000, function() {
    console.log('服务器启动了,可以通过 http://127.0.0.1:3000/来访问');
});

在终端中可以开启服务器 ctrl+c 可以关闭服务器

根据不同请求返回不同响应

server.on('request', function(request, response) {
    var url = request.url;
    if (url == '/') {
        response.end('index page');
    } else if (url == '/login') {
        response.end('login page');
    } else {
        response.end('404 not found');
    }
});

核心模块

node为JavaScript提供了很多服务器级别的API,这些API绝大多数被包装到了一个具名的核心模块中 例如fs http pash os
require用于加载模块

// os 是炒作系统的Api
var os = require('os');
//获取cpu信息
console.log(os.cpus());
// 获取内存信息
console.log(os.totalmem());

// path 用于处理路径的核心模块
var path = require('path');
path.extname('a/b/c/hello.txt');

执行多个js文件–模块化编程

在js中需要模块化编程 在一个js文件中执行多个js文件
require(‘文件’);require用于在js中调用文件
实例:在核心模块.js中执行核心模块2.js

var http = require('http');
var server = http.createServer();
server.on('request', function(req, res) {
    var foo = 'aaa';
    console.log(foo);
    require('./核心模块2');
})
server.listen(3000, function() {
    console.log('服务器可以在http://127.0.0.1:3000/');
});

先输出了aaa 后输出了bbb
、、
、、
、、
、、

在node中只有模块作用域(文件之间不会影响,每个文件中的变量只能自己访问)没有全局作用域
内部无法访问外部
外部无法访问内部
模块作用域可以避免命名冲突

当模块间需要通信时

在这里插入图片描述

模块有三种:

1.核心模块:node提供的具名的模块,都有自己的特殊标识: fs(文件操作模块),http(网络服务构建模块),os操作模块(操作信息模块) path路径处理模块
所有核心模块都需要require来加载

2.用户自己编写的文件模快

、、、、、、、、、
、、、、、、、、、、
、、、、、、、、、、、、
、、、、、、、、、、、、、、、、、
、、、、、、、、、、、、、、、、、、

端口号

服务器:24小时不关机的主机
IP:用来定位计算机
端口号:用来定位具体应用程序 (所有需要联网通信时都要端口号)服务器中的软件有各自的端口号,客户端也有端口号和IP地址
在这里插入图片描述
一些知名的端口号已经被占用 不要使用 例如80
在这里插入图片描述

浏览器对服务器response内容的解析 Content-type设置

1.当服务器发送的是中文
在这里插入图片描述

服务端发送的内容是utf8编码的内容
浏览器不知道而是以浏览器默认的gbk编码来解读,解决方法是 服务端告诉浏览器所需要的编码方式

 // 当端口号是简体   plain表示普通文本   charset 为编码方式
    if (url == '/plain') {
        res.setHeader('Content-type', 'text/plain;charset=utf-8'); //设置编码方式
        res.end('中文编码');

2.当服务器发送了html

//当端口是html    要想解析html文件:text/html   html中如果有中文:charset = utf-8
    else if (url == '/html') {
        res.setHeader('Content-type', 'text/html;charset=utf-8'); //设置为html编码方式   可以解决乱码问题 但是 html不能被识别出来
        res.end('<h1> hello 邓柱沙发 </h1>');
    }

、、、、、、、、、、、、、、、
、、、、、、、、、、、、、、、、
、、、、、、、、、、
、、、、、、、、、、、、、、
、、、、、、、、、、、、、、、、
、、、、、、、、、、、、、、、

服务器返回文件中的内容(本质上讲不能发送文件只能发送内容)

服务器是动态读取文件,当文件内容改变时 不需要重启服务器
通过fs.readFile()读取其他文件中的html
data 就是文件中的字符串

var http = require('http');
var server = http.createServer();
var fs = require('fs');
server.on('request', function(req, res) {
    var url = req.url;
    if (url === '/') {
        //  文件位置前是两个点  文件读取时不管位置在哪默认加./
        fs.readFile('../resource/index.html', function(error, data) {
            if (error) {
                res.setHeader('Content-type', 'text/plain;charset=utf-8');
                res.end('读取错误');
            } else {
                //因为data 默认是二进制数据 可以通过 .toString()转化为字符串
                //res.end()支持两种数据   二进制 或 字符串
                res.setHeader('Content-type', 'text/html;charset=utf-8');
                res.end(data);
            }
        })
    }
});

图片读取

var http = require('http');
var server = http.createServer();
var fs = require('fs');
server.on('request', function(req, res) {
    var url = req.url;
    if (url === '/') {
        //  文件位置前是两个点  文件读取时不管位置在哪默认加./
        fs.readFile('../resource/index.html', function(error, data) {
            if (error) {
                res.setHeader('Content-type', 'text/plain;charset=utf-8');
                res.end('读取错误');
            } else {
                //因为data 默认是二进制数据 可以通过 .toString()转化为字符串
                //res.end()支持两种数据   二进制 或 字符串
                res.setHeader('Content-type', 'text/html;charset=utf-8');
                res.end(data);
            }
        })
    }
    //读取图片
    else if (url == '/image') {
        fs.readFile('../resource/1.jpg', function(error, data) {
            if (error) {
                res.setHeader('Content-type', 'text/plain;charset=utf-8');
                res.end('读取错误');
            } else {
                res.setHeader('Content-type', 'image/jpeg');
                res.end(data);
            }
        })
    }
})

server.listen(3001, function() {
    console.log('可以在 http://127.0.0.1:3001/来访问');
})

不同的数据类型 Content-type不同,只有字符内容的数据才需要字符编码,图片不需要

也可以在html中的meta设置编码方式

目录列表渲染

读取文件列表 wwwdir

在node中使用模板引擎

1.安装
npm install art-template(该命令在哪里执行 引擎就会被下载到哪里)
在这里插入图片描述
2.加载模板引擎
require(‘下载的包的名字’);
3.使用模板引擎:查看引擎文档
一定要先把node modules文件放在js相同的文件夹下

var template = require('template');
var ret = template('被赋值的字符串(必须把data转化为字符串	)',赋值得对象);

在node中使用模板引擎

模板引擎的作用:将原html中的文件通过模板引擎 替换数据 再交给浏览器
1.获取template

var template = require('art-template');

2.在html文件中将要替换的数据用{{}}表示

3.替换

var ret = template.render('被赋值的字符串(必须把data转化为字符串	)',赋值得对象);

模板引擎诞生于服务端

服务器渲染和客户端渲染

客户端渲染 :请求二次以上 ,先加载页面,在加载内容 ,加载快(评论)
客户端渲染不利于seo搜索引擎优化,爬虫爬不到信息,百度等搜索引擎搜不到
在这里插入图片描述

服务端渲染: 只请求一次,加载慢(页面),可以被爬虫搜索到 ,利于seo搜索引擎优化
在这里插入图片描述

留言板制作(渲染静态页面)

当客户端向服务器发出请求后,服务器会先处理html页面,对于一些 src ,link中的href属性 客户端(服务器)会自动发起请求,如果服务器无法处理就会一直卡着
我们将静态页面HTML都放在view文件夹中 将所有静态资源(第三方资源如css js img等)都放在public当中
在这里插入图片描述

什么资源可以访问,什么资源不能访问可以通过代码来控制 // 文件中不用考虑相对路径,因为现在所有资源都是通过url来标识的,只能访问以/public开头的url才能访问public中的内容
在这里插入图片描述
comments数组必须在服务器开启外面设置,因为如果放在服务器内,那么每次获取的都是相同的数据,并且每个comments对象都是null-prototype
设置一个comments数组保存留言(先获取数组再替换)
在通过art-template替换内容
var htmlstr = template.render(data.toString(), {
comments: comments
});
res.end(htmlstr);

处理表单get提交

表单html设置
action是请求表单的地址 点击提交后就会请求这个地址
method是请求方法
post get
在这里插入图片描述

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210110233954348.png)

点提交后会将name的值放在url中
url核心模块

 var url = require('url');
    // url.parse('路径');能将路径解析为一个方便操作的对象,第二个参数为true表示直接将查询字符串转化为对象(query)
    var parseObject = url.parse(req.url, true);
    // parseObject.parthname就得到不包含    查询字符串的路径部分(该路径不包括?之后的内容);
    var pathname = parseObject.pathname;

必须放在url的前面
parseObject.query就是得到的表单数据形成的对象:
在这里插入图片描述

表单提交重定向

一次请求对应一次响应
步骤:
在这里插入图片描述
1.获取表单的数据

   var comment = parseObject.query;
        comment.dateTime = '2021-1-10';//comment对象中添加dateTime属性
        comments.push(comment);

2.重新定向跳转
1.状态码设置为302重定向
res.statasCode
2.在响应头中通过location告诉客户端哪重定向
res.setHeader(‘location’,‘要跳转的url’)
如果服务器的响应的状态码是302就会自动 自动去响应头 location
后面一定要以 res.end()结尾

  res.statusCode = 302;
        res.setHeader('location', ' / ');
        res.end(); //必须要加上

node留言白制作步骤总结

在这里插入图片描述

模块系统–基本法则

模块就是文件
使用node编写应用程序主要使用:
1.EcmaScript语言:没有BOM DOM
2.核心模块:
文件操作的fs
http服务的http
url路径操作
path路径处理模块
os操作系统信息
3.第三方模块
art-template
4.自己写的模块

什么是模块化

1.文件作用域
2.通信规则:
加载require
导出

commonJS模块规范

在node中有一个重要的概念:模块系统
· 模块作用域
在这里插入图片描述
只能加载一个文件中的变量,即使require了另外一个文件只要该文件不给变量就无法访问
在这里插入图片描述

· 使用require方法来加载模块

· 使用exports接口对象来导出模块中的成员

exports是一个对象
导出多个成员就必须是对象
可以通过这个对象添加多个成员 exports.方法得到的是一个对象的形式

exports.a ='123';
exports.d=function(){
console.log('sf')
}

在这里插入图片描述
或者用这个方法导出

module.exports = {
add:{}
str='hello'
}



导出单个成员
如果想直接得到某个方法则需要一下形式:

var foo = 'bar';

function add(x, y) {
    return x + y;
}
module.exports = add;

在这里插入图片描述

以下情况后者会覆盖前者:
在这里插入图片描述

exports和module.exports的区别原理

在node中每个模块内部都有一个自己的 module对象
在module对象中有一个exports也是一个对象

var module={
exports:{
}
}

又因为module.exports =exports 所以exports.a == module.exports.a 相当于其实实在 module.exports中添加对象
谁来require这个文件就会得到module.exports
在默认的代码最后都有一句:
return module.exports

优先从缓冲加载

同一个文件如果被两个文件require了 不会重复加载,但是能得到接口对象module.exports
在这里插入图片描述
避免重复加载,提高加载效率

require加载规则

模块标识:
1.核心模块 2.第三方模块 3.自定义模块
路径形式的模块: ./ …/ /xxx
核心模块的本质还是文件
第三方模块:凡是第三方模块都需用npm下载,用require包名来加载使用,··· 加载原理:先找到当前文件所在目录中的node-modules文件,再找到art-template,再加载package.json文件中的main 如果main中没有内容就会加载index.js文件(当没有package.json文件也会加载index.js)
如果级目录找不到package.js 和 index.js 就到上上一级从新寻找 直到找到为止,否则报错每个项目只有一个node-modules文件

包说明文件

package.json
建议每个demo都需要一个说明文件来进行说明 引用了哪些第三方包(就像说明书一样)
可以通过 npm init来创建
下载第三方包时加上 --save可以显示版本
在这里插入图片描述
在这里插入图片描述
会显示第三包的版本信息
如果第三方包被删除了 在 cmd中输入 npm install 会自动下载package.json 中dependency中的所有第三方文件

npm常用命令

npm网站:npmjs.com
可以在cmd中输入npm --version查找版本
升级npm:

npm install – global npm

npm常用命令:

npm install -y可以跳过向导,快速生成
npm install 只下载 一次性将dependencies中的依赖项全部安装
npm install – save包名 下载并保存依赖项(package.json 文件中的 dependencie选项)
npm uninstall 包名 只删除依赖项会保存
npm uninstall --save包名 删除的同时会把依赖项删除
npm --help 查看使用 命令帮助

npm被墙下载过慢问题

解决方式:安装淘宝的cnpm

npm install --global cnpm
–global 不能省略 表示安装到全局 使用cnpm就会用淘宝的服务器下载 jquery

不用下载cnpm使用淘宝镜像源的方法:

npm config set registry https://registry.npm.taobao.org
输入上面代码后 以后用 npm 下载自动用淘宝的镜像下载了
npm config list 查看 registry 地址

express

原生的http在某些方面不足以满足我们的开发需求,所以我们需要用框架来加快开发效率,框架的目的就是提高效率,让我们的代码高度统一
下载:
在这里插入图片描述

express的使用

当访问不同的url时不需要再用 if else 中文也不用再 设置
注意是 res.send()结束

var express = require('express');
var app = express();
app.get('/', function(req, res) {

    res.send('hello express');
});
app.get('/about', function(req, res) {

    res.end('about me');
});
app.listen(3000, function() {
    console.log('可以在http://127.0.0.1:3000访问');
});

在这里插入图片描述

能自动识别html文件内容

var express = require('express');
var app = express();
app.get('/', function(req, res) {

    res.send('hello express');
});
app.get('/about', function(req, res) {

    res.send(`<!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <h1>hello express</h1>
    </body>
    
    </html>`);
});
app.listen(3000, function() {
    console.log('可以在http://127.0.0.1:3000访问');
});

通过app.use()公开public资源

公开指定目录

app.use('/public/', express.static('./public/'));

这样就可以在网址中访问文件
通过省略/public/来访问,这个时候不能输入/public/某某某

// 开放资源 当use中没有 /public/表示不用加/public/就能访问资源
app.use(express.static('./public/'));

通过自定义别名访问 必须输入/别名/某 来访问某文件 相当于此时a就是public文件夹的别名

app.use('/a/', express.static('./public/'));

这里必须用/a/index.html 来访问public相对路径中的文件

修改完代码自动重启(在VScode中无效)

使用第三方命名航工具:nodemon来解决频繁修改代码重启服务器问题
下载软件方法

npm install – global nodemon
只能在cmd中下载 在vscode中输入下载命令无效
nodemon 会监视文件的变化,当文件发生改变时,自动帮你重启服务器
使用方法:

nodemon +js文件名启动服务器

启动的时候如果没有设置换进变量可以在脚本中设置 用npm启动
在这里插入图片描述

npm run nodemon app.js

express中的静态资源服务

基本路由

在这里插入图片描述

在express中使用art-template引擎(不能在vs code中使用有BUG)

安装art-template
npm install --save art-template express-art-template
必须安装art-template
配置express-art-template(express-art-template是专门用于express中的)

// 配置express-art-template文件,art为要配置的文件类型
app.engine('art', require('express-art-template'));

使用express-art-template
如果配置了模板引擎,express就可以使用render方法

res.render('html模板名',{模板数据});

第一个参数不能写路径默认会在views中寻找改文件,因此将页面文件都放在views文件中
文件后缀名必须是app.engine(‘后缀名’,require())中设置的
如果想要修改render的默认查找路径可以用 app.set(‘名称’,目录路径)

处理数据
在get型表单中通过req.query获取数据
res.redirect(‘路径’)从定向

app.get('/comment', function(req, res) {
//获得数据
    var comment = req.query;
    comment.dateTime = '2021-1-23-12:00'
    comments.unshift(comment);
    // 重定向
    res.redirect('/');
})

express表单用post请求数据

post常用于处理数据比较多的表单
在express中获得POST表单数据
只能通过第三方bodyParser来获取
1.安装bodyParser插件

npm install --save body-parser

2.配置

var bodyParser = require(‘body-parser’);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

3.使用
就将req.query改为req.body

app.post('/comment', function(req, res) {
    var comment = req.body;
    console.log(req.body);
    comment.dateTime = '2021-1-23-12:00'
    comments.push(comment);
    // 重定向
    res.redirect('/');
});

crud起步

下载bootstrap模板
到官网复制模板源代码,放到新建的index.html中
下载bootstrap(注意模板用的什么版本就要下载什么版本的bootstrap)

npm install --save bootstrap 或者 npm install --save bootstrap@3.3.7

将模板中的href 链接都改到自己的 public 文件中 和 node_modules文件中
在这里插入图片描述替换数据

从文件中读取数据

fs.readFile中间加了utf-8可以使文件从二进制转化为可识别的代码
JSON.parse(data).students是将data由字符串转化为对象

  fs.readFile('./db.json', 'utf-8', function(err, data) {
        if (err) {
            return res.status(500).send('Sever error');
        } else {
            res.render('index.html', {
                fruits: ['苹果', '香蕉', '花生', '面包'],
                // 读取文件data中的数据   data是字符串需要转换为对象   JSON.parse(data)是将data转化为对象,.students是为了赋值
                students: JSON.parse(data).students
            });
        }

路由设计

在这里插入图片描述

express中的路由模块的提取

1.用express提供的router来做路由,首先创建一个路由容器
var router = express.Router();
2.把路由挂载在router路由容器中
router.get(’/students’,function(){
)
router.get(’/students’,function(){
);
router.get(’/students/new’,function(){
);
3.在router.js文件中 导出 router
modules.exports=router;
3.将路由挂载到app.js的APP服务中
app.use(router);
app.js是入口模块的职责
在这里插入图片描述

router.js路由模块的职责
处理路由
设置具体的函数

模块职责单一,不要乱写

划分模块快的目的为了增强代码的可维护性

提升开发效率

crud处理页面及配置body-parser中间件

bodyparser的配置必须在挂载router之前 及 只能在app.js中 配置,不能在router.js中配置
在文件中添加数据
先将文件读取出来,转化为对象,然后往对象中push数据,把对象转化为字符串,再将字符串写入文件

封装提取student数据模块–数据操作文件模块

操作文件中的数据,只处理数据,不关心业务
只是对数据进行增删改查

异步编程

每一个任务有一个或多个回调函数(callback),后一个任务则是不等前一个任务结束就执行,前一个任务结束后,不是执行后一个任务,而是执行回调函数,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。换一种说法就是一个任务分成两段,先执行第一段,然后转而执行其他任务,等做好准备再回过头执行第二段(这个第二段就是我们说的回调)
**fs读取文件就是异步编程 **

封装异步API:访问异步函数的结果,需要用回调函数去访问

在这里插入图片描述
如果要获取一个函数中异步操作的结果,则必须通过回调函数来获取
在这里插入图片描述

exports.find = function(callback) {
        fs.readFile(dbpath, function(err, data) {
            // callback中的参数  : 第一个参数是err  成功是null  错误是错误对象   第二个参数是结果   成功是数组   错误是undefined
            if (err) {
                return callback(err);//如果err出现就回调给callback,callback中执行err的业务
            }
            //如果没有 err  就执行没err的业务
            callback(null, JSON.parse(data).students);
        });
    }

将student.js引入到router.js中 调用find方法读取文件

var Student = require('./student.js');
router.get('/students', function(req, res) {
    // fs.readFile('./db.json', 'utf-8', function(err, data) {
    //     if (err) {
    //         return res.status(500).send('Sever error');
    //     } else {
    //         res.render('index.html', {
    //             fruits: ['苹果', '香蕉', '花生', '面包'],
    //             // 读取文件data中的数据   data是字符串需要转换为对象   JSON.parse(data)是将data转化为对象,.students是为了赋值
    //             students: JSON.parse(data).students
    //         });
    //     }
    // });
    Student.find(function(err, students) {
        if (err) {
            return res.status(500).send('Sever error');
        } else {
            res.render('index.html', {
                fruits: ['苹果', '香蕉', '花生', '面包'],
                // 读取文件data中的数据   data是字符串需要转换为对象   JSON.parse(data)是将data转化为对象,.students是为了赋值
                students: students
            });
        }
    });
})

*补充:表单中要提交的 数据 必须设置name 服务器才能获得该数据 value 的只就是要提交的值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值