全局对象:
js中包含的settimeout,setInterval
还有js中没有的如_dirname//打印当前路径
console.log(__filename)//打印文件名称
模块(commmonJS规范)
再utiles工具js文件中设置两个方法
function adder(a, b) {
return `the result of those two number is ${a + b}`
}
function counter(a, b) {
return `the result of those two numbers is A${a * b}`
}
并导出module.export
方式一:
module.exports = {
counter: counter,
adder: function adder(a, b) {
return `the result of those two number is ${a + b}`
},
}
方式二:
module.exports.counter = counter
module.exports.adder = adder
module.exports={
counter:counter,
adder:adder
}
以为多个导出默认为对象,所以以上两种方式都可以
在index主文件夹中用点语法的方法require引入
const utils = require('./utils.js')
console.log(utils.counter(10, 20))
console.log(utils.adder(10, 20))
总之导入时require(文件路径);导出module.export(不要和js中moudel混淆import和export default)
ECMAScript 标准(ES6)
默认标准使用:
1. 导出:export default {}
2. 导入:import 变量名 from '模块名或路径'
注意:Node.js 默认支持 CommonJS 标准语法
如需使用 ECMAScript 标准语法,在运行模块所在文件夹新建 package.json 文件,并设置 { "type" : "module" }
事件
//声明事件
var event=require("events")
//创建事件对象
var myEmitter=new events.EventEmitter()
//设置事件监听器
myEmitter.on("someEvent",function(message){
console.log(message)
})
//触发事件
myEmitter.emit("someEvent","the event was emitted")
定义 Person 构造函数
require("events")
:这是Node.js的模块加载机制,用于引入内置的events
模块。events
模块是Node.js的核心模块之一,提供了事件发射器(EventEmitter)类,用于管理和触发事件。ar myEmitter
:将新创建的EventEmitter
实例赋值给变量myEmitter
。这个变量myEmitter
现在就是一个事件发射器,可以用来触发和监听事件。- 其实和js中onCick监听事件差不多,只不过它的触发时文件提交,读取等后端操作。
-
引入模块
var event = require("events"); var util = require("util");
require("events")
:引入内置的events
模块,该模块提供了EventEmitter
类,用于管理和触发事件。require("util")
:引入内置的util
模块,该模块提供了一系列实用工具,如inherits
方法用于实现继承。
var Person = function (name) {
this.name = name;
}
继承 EventEmitter(相当于es6中extends后用super())
util.inherits(Person, event.EventEmitter);
var xiaoming = new Person('xiaoming')
var lilei = new Person('lilei')
var persons = [xiaoming, lilei]
每个 Person 实例添加事件监听
person.forEach(function(item){
item.on("speak", function (message){
console.log(item.name + " says: " + message);
})
})
- 使用
forEach
方法遍历person
数组。 - 为每个
Person
实例添加一个名为 “speak” 的事件监听器。 - 当 “speak” 事件被触发时,执行回调函数,打印出 person 的名字和传递的消息。
触发事件
xiaoming.emit("speak", "hi");
文件的读写
读
同步方法
var fs = require('fs')
var readMe = fs.readFileSync('./readMe.txt', 'utf8')
console.log(readMe)
其中require('fs')
:引入 Node.js 的内置文件系统模块(fs),该模块提供了一系列用于与文件系统交互的方法。'utf8'
表示使用 UTF-8 编码,这样读取出的内容将是字符串形式。
fs.readFileSync
:使用文件系统模块的 readFileSync
方法同步读取文件。
异步方法
var readME=fs.readFile("./readMe.txt","utf8",function(err,data){
console.log('读取文件成功');
})
写
执行后会直接生成对应文件,并把文件内容加进去
也是同步方法
fs.writeFileSync('writeMe.txt', readMe)
异步方法
fs.writeFile('./writeMe.txt', 'Hello, World!', 'utf8', function(err) {
if (err) {
return console.error(err);
}
console.log('文件写入成功!');
});
流
如果文件比较小,可以采用文件的读取和写的方式。如果文件大用流的方式;平时前后端交互就是转换成流来进行交互的,文件的读写也属于流的操作。
ls
ls |grep app//linux或mac
dir | findstr app//windows中查找文件操作
如流的输出就可以在命令行中操作
首先要知道chunk,和buffer两个概念
Buffer:
- 定义:Buffer 是 Node.js 中用于处理二进制数据的类。它是一个全局类,无需引入即可使用。
- 用途:Buffer 用于存储原始数据,如文件内容、网络数据等
Chunk:
定义:Chunk 通常指的是数据流(Stream)中的数据片段。当你从可读流(如文件读取流)中读取数据时,数据会被分成多个小的片段,每个片段就是一个 Chunk。
function startServer() {
var server = http.createServer(function (req, res) {
console.log('request received');
if(req.url === "/" || req.url === "/home"){
res.writeHead(200, {'Content-Type': 'text/html'});
fs.createReadStream(__dirname + "/home.html", "utf8").pipe(res);
}
else if(req.url === "/api/user"){
res.writeHead(200, {"Content-Type": 'application/json'});
var obj = { /* ... */ }; // 定义 obj 对象
res.end(JSON.stringify(obj));
else {
res.writeHead(404, {"Content-Type": 'text/html'});
fs.createReadStream(__dirname + "/404.html", "utf8").pipe(res);
server.listen(3000, '127.0.0.1', function () {
console.log('服务器运行在3000端口上');
});
module.exports = {
startServer: startServer
};
运行 npm init
后,npm 会提示你输入这些信息。你可以直接回车接受默认值,或者输入你自己的信息。完成这个过程后,npm 会生成一个 package.json
文件在你的项目目录中。
应用:在终端下载gulp:在终端输入cnpm install --save express或者cnpm install --save-dev gulp
其中-save和--save-dev的区别:--save是生产环境,--save-dev是开发环境
如果在别人看到你的项目是只需要用cnpm/npm install自动安装包(网络好就用npm)
- 类型:Chunk 可以是 Buffer 对象,也可以是字符串,这取决于流的编码设置。如果流被设置为某种编码(如 ‘utf8’),则 Chunk 会是字符串;否则,Chunk 默认是 Buffer 对象。
-
在 Node.js 中,无论您传入的是字符串还是 Buffer 对象,最终在底层系统中都会被转换为 Buffer 类存在缓存区。这是因为 Node.js 的许多底层操作,如文件系统操作、网络传输等,都是基于二进制数据进行的,而 Buffer 正是用于表示二进制数据的。
-
但是不管data是字符串类型还是buffer类型存入,最后都会在转为buffer对象
-
字符串转换为 Buffer:
- 当您向可写流(如文件写入流)写入字符串数据时,Node.js 会自动将字符串转换为 Buffer 对象。这是通过将字符串编码为特定的字符编码(如 UTF-8)来实现的。
-
Buffer 对象直接存储:
- 如果您传入的是 Buffer 对象,则直接存储在内部的缓存区中,无需进行转换。
-
内部缓存区的管理:
- 无论原始数据是字符串还是 Buffer 对象,Node.js 都会使用 Buffer 对象来管理内部的缓存区。这个缓存区 acts as an intermediary storage,即作为中间存储,用于在数据实际写入底层系统之前暂时存储数据。
-
底层系统的操作:
- 当数据从缓存区写入底层系统时由end标志写入结束,无论是文件系统、网络连接还是其他系统,都是基于二进制数据进行的。因此,无论原始数据类型如何,最终都会以 Buffer 的形式进行处理。
-
流——读取数据
-
在 Node.js 中,当使用流来读取文件时,文件会被分成多个小的数据块(chunk),每个数据块通常是几百到几千字节大小。通过监听可读流的
data
事件,可以接收到这些数据块。下面代码,通过
data += chunk
的方式,将每个接收到的数据块拼接到data
变量中。随着文件的逐步读取,data
变量会逐渐积累所有的数据块,最终形成一个包含整个文件内容的大字符串。 -
data
变量最终会包含readMe.txt
文件的全部内容。每次data
事件触发时,都会有一个数据块被添加到data
中,直到end
事件触发,表示文件读取完成。 -
var fs = require("fs"); var data = ""; var myReadStream = fs.createReadStream(__dirname + '/readMe.txt', "utf8"); 下面方法也可以用来utf8字符串 //var myReaderStearm = fs.createReadStream(__dirname + '/readMe.txt') //myReaderStearm.setEcoding("utf8") myReadStream.on("data", function(chunk) { data += chunk; // 将每个数据块拼接到data变量中 }); myReadStream.on("end", function() { console.log(data); // 文件读取完成后,data变量包含整个文件内容 });
-
流——写入数据
- 可以将读取后的文件写入
-
var myReaderStream = fs.createWriteStream(__dirname + '/readMe.txt', 'utf8') var myWriteStream=fs.createWriteStream(__dirname+"/writeMe.txt") var data="" myReaderStearm.on('data',function(chunk){ myWriteStream.write(chunk) }) myReaderStream.on('end', function () { console.log('读取文件结束') })
- 直接写入文件
-
var fs=require("fs") var myData="hello Node" var myWriteStream=fs.createWriteStream(__dirname+"writeMe.txt") myWriteStream.write(myData) myWriteStream.end() myWriteStream.on(finish,function(){ console.log('写入完成'); })
myWriteStream.end()
:这个方法用于结束可写流。调用这个方法后,不再允许向流中写入更多的数据。这个方法会触发finish
事件,表示所有数据已经写入到底层系统。-
管道
pipe
方法用于将可读流中的数据传输到可写流。- 这里,
myReaderStream
读取的文件内容会被自动写入到myWriteStream
指定的文件中。 -
// var fs = require('fs') // var myReaderStream = fs.createReadStream(__dirname + '/readMe.txt', 'utf8') // var myWriteStream = fs.createWriteStream(__dirname + '/readMe.txt', 'utf8') // myReaderStream.pipe(myWriteStream)
Web服务器输出内容
-
可以支持纯文本,html和JSON文件
-
纯文本
-
-
var http = require('http') var server = http.createServer(function (req, res) { console.log('request received') res.writeHead(200, { 'Content-Type': 'text/plain', }) res.end('hello from our application') }) server.listen(3000, '127.0.0.1', function () { console.log('服务器运行在3000端口上') })
- 创建一个名为
http
的变量,并将 Node.js 的http
模块赋值给这个变量 http.createServer()
:这个方法用于创建一个新的 HTTP 服务器,并返回一个服务器实例。function (req, res)
:这个回调函数会在每次接收到客户端请求时被调用。它接收两个参数:req
:请求对象,包含了客户端请求的所有信息,如请求方法、URL、头部等。res
:响应对象,用于发送响应回客户端。
console.log('request received')
:在控制台打印一条消息,表示收到了请求。res.writeHead(200, {'Content-Type': 'text/plain'})
:设置响应状态码为 200,表示请求成功,并设置响应头Content-Type
为text/plain
,表示响应内容是纯文本。res.end('hello from our application')
:结束响应,并返回一段文本内容给客户端。- HTMl
-
var fs = require('fs'); // 正确引入fs模块 var http = require('http'); var server = http.createServer(function (req, res) { console.log('request received'); res.writeHead(200, { 'Content-Type': 'text/html', // 更改为HTML类型 }); var myReaderStream = fs.createReadStream(__dirname + "/index.html", "utf8"); // 使用fs myReaderStream.pipe(res); }); server.listen(3000, '127.0.0.1', function () { console.log('服务器运行在3000端口上'); });
JSON
-
var http = require('http') var fs=require('fs') function startServer(){ var server = http.createServer(function (req, res) { console.log('request received') res.writeHead(200, { 'Content-Type': 'application/json', // 修改为JSON类型 }) const obj={ "name": "'itral'", "age": 20 } res.end(JSON.stringify(obj)) }) server.listen(3000, '127.0.0.1', function () { console.log('服务器运行在3000端口上') }) }
模块化
-
index.html作为主入口文件
-
server.js作为服务文件
-
data.json作为提供数据
-
在sever中启动服务器,然后导出
-
function startServer(){ 中间代码同上 } moudle.export={ startServer }
在index.js中导入服务器模块调用startServer方法
-
const server=require("./fuwuqi.js") server.startServer()
data.json中存入数据
-
{ "name": "'itral'", "age": 20 }
路由
-
以下代码是一个简单的 Node.js HTTP 服务器,它根据请求的 URL 路径返回不同的内容:如果是根路径或"/home",则返回"home.html"文件;如果是"/api/user",则返回一个 JSON 对象;否则返回"404.html"文件表示未找到资源。服务器监听本机的3000端口。
-
首先是完整代码
-
var http = require('http') var fs = require('fs') function startServer() { var server = http.createServer(function (require, res) { console.log('request received') if (require.url == '/' || require.url === '/home') { res.writeHead(200, { 'Content-Type': 'text/html' }) fs.createReadStream(_dirname + '/home.html', 'utf8').pipe(res) } else if (require.url === '/api/user') { res.writeHead(200, { 'Content-Type': 'application/json' }) res.end(JSON.stringify(obj)) } else { res.writeHead(404, { 'Content-Type': 'text/html' }) res.createReadStream(_dirname + '/404.html',"utf8") } }) server.listen(3000, '127.0.0.1', function () { console.log('服务器运行在3000端口上') }) } moudle.export = { startServer, }
下面分步解释
var http = require('http'); var fs = require('fs');
- 引入 Node.js 的
http
模块,用于创建 HTTP 服务器。 - 引入 Node.js 的
fs
模块,用于进行文件系统操作。 - 定义一个名为
startServer
的函数,用于启动服务器。 - 使用
http.createServer
方法创建一个 HTTP 服务器,并传入一个回调函数,该函数将在每次接收到请求时执行。req
是请求对象,res
是响应对象。 - 在控制台打印一条消息,表示收到了请求。
- 检查请求的 URL 是否为根路径(“/”)或"/home"。
- 如果是,设置响应头,状态码为 200(表示成功),内容类型为"text/html"。
- 创建一个可读流,读取当前目录下的"home.html"文件,并将其内容通过管道(pipe)发送给客户端。
- 如果请求的 URL 是"/api/user",则进入此分支。
- 设置响应头,状态码为 200,内容类型为"application/json"。
- 定义一个名为
obj
的对象,这里应该是包含用户数据的对象,但具体内容被省略了。 - 将
obj
对象转换为 JSON 字符串,并结束响应,将数据发送给客户端。 - 如果请求的 URL 不符合上述条件,则进入此分支,表示未找到资源。
- 设置响应头,状态码为 404(表示未找到),内容类型为"text/html"。
- 创建一个可读流,读取当前目录下的"404.html"文件,并将其内容通过管道(pipe)发送给客户端,显示未找到页面的信息。
- 结束请求处理函数。
- 让服务器监听本机(127.0.0.1)的3000端口。
- 当服务器开始监听后,打印一条消息到控制台,表示服务器正在运行。
- 结束
startServer
函数定义。 - 将
startServer
函数导出,以便其他文件可以引入并使用它来启动服务器。 -
重构路由
- 不可能由多个路由就一直else if判断,于是我们需要重构一下
- 创建index.html入口文件——判断地址
//入口 var server=require("./server.js")//导入外部的server文件 var handler=require("./handler.js") var handle={} handle["/"]=handler.home handle["/home"]=handler.home handle["/user"]=handle.user server.startServer(handle)//调用服务器文件中的startServer方法
用映射的方法表示请求路径和路由函数的关系:其中键是请求的路径,值是调用的路由函数
-
就从入口文件中传入handel并在server服务器文件中接收
- 在server中开启服务器——只处理服务器,路由具体交给router
var http=require("http") function startServer(){ var server=http.createserver(function(req,res){ })//创建服务器,并通过接收数据访问的地址不同 server.listen(3000,"127.0.0.1") console.log("服务器运行在3000"); } moudle.export={ startServer//从文件中导出,供外部访问 }
创建handler.js文件用于存放路由在发送到指定地址后返回请求的函数——响应方法
-
var fs=require("fs") function home(response){ res.writeHead(200,{"content-Type:"text/html}) fs.createReadStream(_dirname+"/home.html","utf8").pipe(response) } function user(response){ res.writeHead(200,{"Content-Type":"application/jison"}) fs.createReadStream(_dirname+"/") }
创建data文件提供json数据
-
再创建路由配置文件router,当没有指定路径找到对应函数是返回404,如果找到对应函数就执行——解析地址
var fs = require('fs') function route(handle, pathname, response) { if (typeof handle[pathname] === 'function') { handle[pathname](response) //判断请求的是一个函数 } else { response.writeHead(404, { 'Content-Type': 'text/html' }) fs.createReadStream(__dirname + '/404.html', 'utf8').pipe(response) } } module.exports = route
route在index.js入口文件中引入,,在调用服务器调用时传入router和handelr参数。其中:,
handle
参数代表了一个路由表,它是一个对象,包含了路径到处理函数的映射。router
函数会使用这个路由表来决定如何处理传入的请求。它会根据请求的路径(比如"/user"
)在handle
对象中查找对应的键。如果找到了,就会调用对应的处理函数(比如function.user
),并传入response
对象作为参数。如果未找到,可能会返回一个错误响应,比如 404 Not Found。 -
在server.js中接收handel和route参数,当服务器接收到请求时,它会调用
route
函数来处理请求。var server = http.createServer(function (request, response) { route(handle, request.url, response) }) //创建服务器,并通过接收数据访问的地址不同
具体执行过程如下:
-
用户输入 URL:用户在浏览器的地址栏中输入一个 URL,例如
http://127.0.0.1:3000/home
,并按下回车键。 -
发送请求:浏览器发送一个 HTTP 请求到服务器,请求中包含了用户输入的路径。
-
服务器接收请求:服务器(通过
http.createServer
创建的实例)接收到请求,并触发回调函数。 -
调用 route 函数:在回调函数中,服务器调用
route
函数,并传递handle
对象、request.url
(用户输入的路径)和response
对象作为参数。 -
路由处理:
route
函数根据request.url
查找handle
对象中对应的处理函数。例如,如果request.url
是/home
,那么route
函数会找到handle['/home']
对应的函数handler.home
。 -
执行处理函数:找到对应的处理函数后,
route
函数会调用这个处理函数,并传递response
对象,以便处理函数可以生成并返回响应。 -
post 或get发送数据
-
post
- 当用户在浏览器地址栏中输入URL或者通过点击链接等方式发起GET请求时,参数通常是通过URL的查询字符串传递的例如:http://example.com/page?name=John&age=30
-
解析URL路径:
var pathname = url.parse(request.url).pathname;
这行代码从请求的URL中提取出路径部分,例如
/home
或/user
。 -
解析查询参数:
var params = url.parse(request.url, true).query;
解析URL中的查询字符串,并将其转换为一个对象,其中键是参数名,值是参数值。
-
路由处理:
route(handle, pathname, response, params);
将解析出的路径、响应对象和查询参数传递给路由函数
route
,该函数会根据路径找到对应的处理函数并执行。但是对于需要传递大量数据或敏感信息的情况,通常使用POST请求或其他HTTP方法。request .on('error', function () { console.log(err) }) .on('data', function (chunk) { data.push(chunk) }) .on('end', function () { if (request.method === 'POST') { data = ArrayBuffer.contact(data).toString() route(handle, pathname, response, querystring(data)) } else { var params = url.parse(request.url, true).query route(handle, pathname, response, params) } })
其中data = ArrayBuffer.contat(data).toString()用于将存储在
data
数组中的所有数据块合并成一个单一的Buffer,然后将其转换为字符串。 -
POST请求解读:
- 在HTTP POST请求中,请求体通常包含要发送到服务器的数据。这与GET请求不同,GET请求的数据是通过URL的查询字符串传递的。
- 由于POST请求体可以包含大量数据,这些数据可能会分多个块(chunks)到达服务器。因此,需要监听
data
事件来收集这些数据块。 - 当所有数据块都接收完毕后(
end
事件触发),需要将它们合并成一个完整的缓冲区(Buffer),然后根据需要将其转换为字符串或其他格式。 - 最后,将解析后的数据传递给路由处理函数,以便进一步处理和生成响应。
-
npm命令
- 当团队开发时,一般只需要将js文件等传出,不需要传递node_modules这样的依赖,但是当依赖太多时就需要用package.json来告诉别人我们安装过哪些包
- 如何创建package文件呢?
- 首先在终端输入一个node.js命令:npm init
- 它会引导你通过一系列的步骤来创建一个
package.json
文件, -
包含以下信息:
- name:项目的名称。
- version:项目的版本号。
- description:项目的描述。
- main:项目的入口文件,通常是
index.js
。 - scripts:可以定义一些脚本命令,比如启动项目、测试等。
- keywords:与项目相关的关键词,用于在 npm 搜索时提高可见性。
- author:项目的作者信息。
- license:项目的许可证。
- dependencies:项目生产环境下的依赖列表。
- devDependencies:项目开发环境下的依赖列表。
- 别人得到你的代码尽管没有node.moudle只需要用cnpm/npm install来自动安装包(网络好尽量用npm)
- 或者用--save或--save dev来配置开发环境和生产环境。-g就是全局安装——让电脑居于这环境
- 其中page
- pakage.json文件中
"scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev":"node index.js" },
只要在终端run dev就可以执行index.js文件(用户不用输入文件路径,可以理解为快捷方案)
-
nodemon
-
一种工具,自动检测目录中文件更改时通过重启应用程序来调试基于node的应用程序
-
express框架
-
是一个最小且灵活的 Node.js web 应用框架,它提供了一系列强大的功能用于创建各种 web 应用和 API。 例如创建了一个简单的 web 服务器,当客户端通过 GET 请求访问
/list
路径时,服务器会返回一个包含状态码和用户数组的 JSON 响应。: -
const express = require('express');
- 通过
require
函数引入了 Express 模块。require
是 Node.js 的一个内置函数,用于加载模块。express
是一个常量,用于存储引入的 Express 模块。 - 创建一个 Express 应用实例
-
const app = express();
-
//配置服务器访问地址(路由) app.get('/list', function (req, res) { res.send({ status: 200, results: [ { name: 'iewn', age: '20' }, { name: 'ime', age: 99, }, ], }) }) app.listen(3000, function () { console.log('服务器运行在3000端口上') })
- 通过
app
来配置路由和启动服务器。 -
路由
-
const express = require('express') const app = express() app.get('list', (req, res) => { res.send({ status: 200, info: '测试', }) }) app.post('/login',(req,res)=>{ res.send({ msg:"登录成功" }) }) app.listen(3000, function () { console.log('服务器运行在3000端口上') })
其中post请求可用postman查看
-
路由句柄
-
后续路由非常多,用句柄就是把路由分离开
-
只需创建两个文件,index.js入口文件,router.js路由文件
-
index文件中导入express模块,导入router文件,让express监听3000端口,用use的方法
const express = require('express') const app = express() const router = require('./router') app.use('/api', router) app.listen(3000, function () { console.log('服务器运行在3000端口上') })
其中use只有当请求的路径以
/api
开头时,后面的中间件(在这个例子中是router
)才会被调用。Express 会检查请求的路径是否以/api
开头。如果是,它会将请求传递给router
中间件进行处理 -
在router文件中调用router中的post,get请求,并导出
-
const express = require('express') const router = express.Router() router.get('/list', (req, res) => { res.send({ status: 200, info: '测试', }) }) router.post('/login', (req, res) => { res.send({ msg: '登录成功', }) }) module.exports = router
托管静态文件
-
为提供图像,css文件,js文件之类的静态文件,使用express的内置express.static内置中间函数,例如想实现在页面中渲染出两个图片
-
并且已经将图片保存至public文件夹中的images文件夹中的1.jpeg,2.jpeg
-
cosnt express=require('express') const app=express() app.use(express.static('public')) app.get('/banner',function(req,res){ res.send({ code:200, results:[ {id:1001, name:'mmefn' image:"http://localhost:3000/images/1.jpeg" }, {id:1001, name:'mmefn' image:"http://localhost:3000/images/1.jpeg" } ] }) }) app.listen(3000,function(){ console.log(3000); })
其中用
app.use(express.static('public'))
将public目录下的图片,css文件,js文件对外开放
-
用下面方式访问其中文件
image:"http://localhost:3000/images/1.jpeg"
get和post参数
-
post
-
用以下中间件的方式解析请求头。这个中间件用于解析 HTTP 请求体中的 URL 编码数据(即表单数据),并将其添加到
req.body
对象中。当添加了这行中间件后,Express 就能够自动解析请求体中的数据,使得我们可以通过req.body
访问这些数据 -
app.use(express.urlencoded({ extended: true }));
app.post('/login', (req, res) => { const username=req.body.username const password=res.body.password if(username==='iwen'&&password==='123455') res.send({ msg: '登录成功', }) })else{ res.send({ msg:'用户名密码错误' }) }
get
-
//接收参数user=? app.get('/list', (req, res) => { const url = new URL(req.url, 'http://example.com') const user = url.searchParams.get('user') console.log(user) if (user === 'iwen') { res.send({ msg: user, }) } else { res.send({ msg: '测试', }) } })
其中
-
const user = url.searchParams.get('user')
:这行代码从解析后的 URL 对象中获取查询参数user
的值。searchParams
是一个URLSearchParams
对象,提供了获取和设置 URL 查询参数的方法。get('user')
方法用于获取名为user
的查询参数的值。 -
所以,
user
变量存储的是从请求的网址中提取的user
查询参数的值,这通常用于表示用户名或其他与用户相关的标识信息。例如,如果客户端发出的请求网址是http://example.com/list?user=john
,那么user
变量的值将会是john
。 -
express-generator
-
用于快速生成程序骨架router.get('/',function(res,req,next){ res.send('responsed with a resource') }) router.get('/test',function(req,res,next){ res.send('用户测试') })
- 如果每都从头写对象创建,路由,中间件效率不高
- 在控制台用npx下载generator包
- 为简化每次app.get请求中都要在第一个参数中添加路由,可以在app.js文件中用use的方式,将第一个参数变为路径名
app.use('/',indexRouter) app.use('/users',userRouter)
- 然后再router路由模块文件中直接将第一个路由参数改为“/”
- 完整代码
-
const express = require('express'); const app = express(); // 创建路由器实例 const indexRouter = express.Router(); const userRouter = express.Router(); // 定义首页路由 indexRouter.get('/', (req, res) => { res.send('responded with a resource'); }); // 定义用户测试路由 userRouter.get('/test', (req, res) => { res.send('用户测试'); }); // 使用路由器中间件 app.use('/', indexRouter); app.use('/users', userRouter); // 启动服务器 const PORT = 3000; app.listen(PORT, () => { console.log(`服务器运行在 http://localhost:${PORT}`); });
当访问
http://localhost:3000/
时,会触发indexRouter
的根路由,返回"responded with a resource"。当访问http://localhost:3000/users/test
时,会触发userRouter
的/test
路由,返回"用户测试"。 -
文件上传
- 网页发送一个请求,服务端调用一个规则匹配并处理这个请求
-
文件上传也是用报文形式包含请求行,请求头和请求体
-
<form action="portrait" method="post" enctype="multipart/form-data">
-
所以表单中enctype="multipart/form-data这一属性必不可少,没有它就没有请求信息
express-文件上传
整体流程就是图片从客户端发送给服务端,服务端把文件保存在静态文件夹下,再把将来需要访问的url存储在数据库中,到时候用户访问就把图片路径返回给用户,用户通过img标签结合url再向服务端发送请求
用中间件连接数据库
node不能直接访问数据库,需要中间件让node和数据库连接起来。
首先 创建config.js文件用来连接数据库 提供数据库操作方法
用require方法提供引入数据库
-
用createConnetion方法连接数据库,里面会有用户名等
//连接数据库 提供数据库操作方法 const mysql=require("mysql") const client=mysql.createConnetion({ host:"localhost", usr:"root", password:"", database:"itbaizhan" })
封装执行数据库语句的方法
-
//query:执行数据库语句的方法 function connectMySQL(){ client.query(sql,arr,function(err,result){ if(err){ console.log(err); return } callback (result) }) } module.exports=connectMySQL
模板语法ejs渲染——用于分离html和js(现在用到很少)
-
接口API
- 连接前后端的桥梁
-
相当于一个路由规则,接收客户端发送的请求,并且对客户端发送结果,只不过是json格式
-
会话控制——cookie
-
浏览器给服务器发送请求比如账号,密码等,服务器会给浏览器返回cookie,浏览器会设置cookie
-
express中设置cookie
-
怎么返回cookie呢
-
res.cookie('name','zhangsan')
name设置为键名,键值是zhangssan
app.get('/remove-cookie',(req,res)=>{ res.clearCookie('name') res.send("删除成功") })
-
服务器想:既然浏览器让我设置cookie我就把cookie返在响应头中Set-Cookie name=zhangsan;Path=/中
-
再想服务器发送请求时请求报文就已经携带了cookie,到时候服务器就知道这个请求时张三发的
-
特点:会在关闭浏览器时销毁
-
七天免登录时怎么实现的呢?
-
在res.cookie中设置第三个参数表示生命周期也就是cookie的存活时间(单位是毫秒)
-
res.cookie('name','zhangsan',{maxAge:60*1000})
express中删除cookie
-
只需要调用一个函数
-
express获取cookie
-
下载一个插件cookie-parser
-
相当于一个中间件,用app.use引入
app.use(cookieParser()) app.get("/get-cookie",(req,res)=>{ res.send(`欢迎您${req.cookies.name}`) })
这样就可以对获取的cookie进行一系列操作
-
session通过用户识别实现会话控制
-
首先用户提供账号密码提供给服务器,如果发现数据正确,服务器会给访问者创建对象称之为session对象,其中有用户的邮箱,电话号码等,除此之外还生成独一无二的session—id,有了这个id之后服务器会把信息以响应cookie的形式,浏览器就会把cookie保存起来,下次再想服务器发送请求时会自动携带cookie包含(id),服务器就会把传递过来的id在session池中比对,如果相等的话就知道对应这个id的用户名是谁发送请求。识别客户端的身份。
-
express-session
-
方便在express中进行session操作,connect-mongo方便把session存储在数据库中
-
-
token
- 主要在移动端
-
和cookie和session创建的时间差不多,都是在App向服务端发送请求后创建token后再返回给客户端。和cookie很像不同的是需要手动把得到的token放到报文里,不向cookie自动存入报文中。