node.js安装
一般为了避免安装上一些乱七糟八的软件,我们都选择去官方下载
Node.js中文地址:http://nodejs.cn/
推荐使用稳定版本,推荐下载12版的,版本稳定就不容易出现bug
下载后缀为.msi的版本,这种版本是直接可以安装的,不是压缩包,不需要解压
下载好后,直接双击刚下载的文件,直接点下一步,只有在安装路径的时候改一下安装路径
一般都装载非系统盘上,最好是直接安装在根盘,如果不在根盘安装也不要目录层级太深,路径中不要有空格和中文,其余的全部点下一步就可以了
安装好后,可以测试一下
win+r —》 输入 —》 cmd 回车 —》 输入 node -v 注意中间是有空格的,回车后显示的安装版本就是按照成功的
接下来我们还要来配置一下配置缓存和全局安装路径
我是安装的是D盘根盘,大家安装在哪里路径就自己改一下就好,路径都不建议手写 最好是地址栏复制,不容易出错
先在D盘下创建一个nodejs文件夹,然后
D:\nodejs)下创建文件夹:node_cache、node_global、node_global下创建node_modules
然后win+r输入cmd回车,在DOS窗口里面执行如下命令:
npm config set prefix “D:\nodejs\node_global”
npm config set cache “D:\nodejs\node_cache”
在配置环境变量
我的电脑>右键>属性>高级系统设置>环境变量>系统变量中添加系统变量NODE_PATH
输入路径:D:\nodejs\node_global\node_modules(注意:去地址栏复制,不要手写)
我的电脑>右键>属性>高级系统设置>环境变量>系统变量中找到Path>双击
win10新建(输入D:\nodejs\node_global)
win7加分号(然后输入D:\nodejs\node_global)(注意:去地址栏复制,不要手写)
都配置好后就测试一下
随便打开一个文件夹,地址栏输入cmd敲回车打开DOS小黑窗
输入node -v 敲回车
输入npm -v 敲回车
输入npm i nodemon -g 敲回车
没有报错就成功了
node的一些特点
模块化
node.js的开发是模块化开发的思想
具有一些相同功能的代码 集成为一个模块
模块主要是由:node系统自带的模块 第三方模块和自定义模块组成
第三方模块几乎都是由npm来管理 ==>npm是一个集成了当前世界上最多开源库的生态系统
事件驱动
回调函数是事件驱动的具体实现
非阻塞I/O操作模型
底层c/c++是多线程 为上层js提供异步编程接口,实现CPU多核处理的优势
单线程
node的上层js业务代码是单线程语言
控制台常用指令
在某个文件夹下路径上输入cmd,就会在当前的路径下运行cmd.exe
node xxx.js文件 //用node环境去运行js文件
cls //清除控制台屏幕上的打印信息
ctrl+c //停止程序运行
上下键//输入过的指令历史
http模块
引入http模块
require("http")
创建一个服务器
http.createServer((req,res)=>{})
要监听的端口:ip是访问计算机的标志 端口就可以进入计算机的具体哪一个程序,一般端口小的都是有自己的程序的不是空闲端口,所以一般我们都用8000以上的端口号
app.listen(8081)
设置编码和数据包格式,以免解析乱码
res.setHeader( ' Content-Type ' , 'text/plain; charset=utf8 ')
end(),可以传输数据也可以不传输,它是当前这一次网络请求结束的标志,一旦执行了就断开连接,就像return一样
res.end()
实例
var http = require("http");
var app = http.createServer((req, res)=>{
res.setHeader("Context-Type","text/plain; charset=utf8")
res.end("Welcome")
})
app.listen(8081);
执行结果
node.js中的两个全局变量
在node.js环境中 有两个全局变量 __dirname __filename
- __dirname 当前js文件所在的目录:绝对路径 文件夹(directory)
- __filename 当前js文件的目录:绝对路径
fs模块
http可以传输字符串也可以传输buffer(二进制),使用fs模块读取的文件就是利用二进制来进行传输的## 读取文件
fs.readFile(path,(err,data)=>{})
path 填路径可以使用绝对路径也可以使用相对路径 ,err代表读取文件失败
data代表读取文件成功 ,它是一个buffer类型的数据(二进制数据流) 可以通过toString()转化为字符串
var fs = require("fs");
var http = require("http");
var app = http.createServer((req, res) => {
/* 可以传输字符串,也可以传输二进制的文件 */
if (req.url == "/img") {
fs.readFile("./img/people.png", (err, data) => {
if (!err) {
res.end(data);
}
})
}
})
执行结果
读取文件
读出来的是 buffer二进制 的文件
这写出来是一个文件路径,是读取不了的,readFile只能读文件
var fs = require("fs");
var path = __dirname;
// 这写出来是一个文件路径,是读取不了的,readFile只能读文件
fs.readFile(path,(err,data) => {
})
readFile中间还有有一个参数,可以设置字符集,但是一般不写,会默认去解析,例如如果读的是视频时但写utf8就会出问题的,所以一般不写
fs.readFile(__dirname+"/01-dirname.js",(err,data)=>{
console.log(err,data);
})
写入文件信息
路径中有这个文件就重写,没有就创建一个,但是如果文件夹都没有就会报错哦
fs.writeFile(__dirname+"/a.txt","hello,good",function(data){
console.log(data);
})
fs.writeFile(__dirname+"/b.txt","hello,good",function(data){
console.log(data);
})
删除文件
如果遇到删除不了的文件有可能就是有权限问题,会删除失败
fs.unlink(__dirname+"/b.txt",(del)=>{
console.log(del)
})
在文件末尾写入信息
以追加的方式写文件,写在最末尾的,相当于拼接,没有这个文件就会自己创建,跟写文件一样的用法
fs.appendFile(__dirname+"/a.txt","马上放学吃饭咯",(data)=>{
console.log(data)
})
创建文件夹
fs.mkdir(__dirname+"/src",(data)=>{
console.log(data);
})
移动或重命名文件夹或者文件
如果原来的文件夹或文件不存在就会失败
var oldpath = __dirname+"/a.txt"
var newpath = __dirname+"/src/a.txt"
fs.rename(oldpath,newpath,(err)=>{
console.log(err);
})
// 重命名
var oldpath = __dirname+"/src/a.txt"
var newpath = __dirname+"/src/b.txt"
fs.rename(oldpath,newpath,(err)=>{
console.log(err);
})
拷贝
因为上面的移动的那个方法有bug,就是非同一个根盘的文件不能移动,就是不能从上c盘移动到d盘
var oldpath = __dirname+"/src/b.txt"
var newpath = __dirname+"/b.txt"
// 只能在copy里面写删除,因为这些都是程序都是异步执行的,我们不能保证在删除前就拷贝成功了
fs.copyFile(oldpath,newpath,(err)=>{
fs.unlink(oldpath,()=>{})
})
以上的console.log()返回的全是null,返回null就代表成功了,这里我就不一一贴图出来了,大家尝试的时候也要注意自己的文件路径,我是写的我的文件路径,你们的不一定跟我一样
读取一个文件夹里面的所有文件和文件夹
fs.readdir(__dirname,(err,arr)=>{
console.log(err,arr)
})
执行结果
URL模块
网址的组成:协议 域名 pathname querystring hash
这个模块主要用于网址的剪切
如果用户输入的是后面带有问号的网址,那么返回过来的数据就找不到文件,所以我们需要先剪切出自己想要的部分在去与__dirname拼接,成为一个可用的路径
实例
var url = require("url");
var str = "http://www.hqyj.com/20022202/news/pag1/index.html?count=20&maxid=1234"
var obj = url.parse(str);
console.log(obj);
执行结果
与fs模块和http模块一起用的实例
var http = require("http")
var fs = require("fs")
var url=require("url")
//用户输入的网址:"http://ip:port/20220728/news/page1/index.html?count=20&maxid=123456"
var app = http.createServer((req, res) => {
//我们获得的范湖数据:"/20220728/news/page1/index.html?count=20&maxid=123456"
console.log(req.url)
var path=url.parse(req.url).pathname
fs.readFile(__dirname + path, (err, data) => {
res.end(data)
})
})
app.listen(8081)
querystring模块
可以把querystring参数解析为一个对象,一般用于操作数据库数据,这么目前就不详细介绍了
var urlobj=url.parse(req.url)
var queryobj=querystring.parse(urlobj.query)
实例
var querystring = require("querystring");
var obj = querystring.parse("username=jack&count=2&maxid=123456")
console.log(obj);
执行结果![在这里插入图片描述](https://img-blog.csdnimg.cn/5501f50abea94c93a21519ae66709895.png)
一个简单的静态网站
var url=require("url")
var querystring=require("querystring")
var http=require("http")
var fs=require("fs")
var app=http.createServer((req,res)=>{
let urlobj=url.parse(req.url)
let pathname=urlobj.pathname
if(pathname=="/"){pathname="/index.html"}
let path=__dirname+"/src"+pathname
fs.readFile(path,(err,data)=>{
if(!err){
res.setHeader("content-Type","text/html")
res.end(data)
}
else if(pathname=="/login"){
let queryobj=querystring.parse(urlobj.query)
console.log(queryobj)
//把前端传过来的数据 去处理
res.end("hello")
}
else if(pathname=="/car"){
res.end("car")
}
else {
res.end("404 not found")
}
})
})
app.listen(8080)
自己要注意路径哦,不要写错了
mime模块
这是第三方的库,所以需要自己下载一下,下载也很简单 npm i mime
这就下载完成,可以引入了
这个主要是用于来确定文件类型的
实例
var mime=require("mime")
var re=mime.getExtension("text/css")
console.log(re)
var re2=mime.getType("htpp://2342354345:8080/css/sadfsdgfdfg.ttf")
console.log(re2)
执行结果
各种相对绝对路径问题
本地相对路径,本地绝对路径
相对网络路径,绝对网络路径
本地相对根路径,网络相对根路径
-
本地相对路径
页面是本地打开的,在这个页面中写路径:“./src/1.jpg” 或者 “src/1.jpg”
写这个路径的文件的页面是在本地打开的 其实它的前缀也有是"file://C:/xx" -
本地绝对路径
从根盘开始写路径,C盘,D盘就是和根盘 -
相对网络路径
当前页面的网址: “协议://IP:port (/src/news/index.html)pathname querystring hash”
页面内部的路径: “./src/1.jpg” --> “协议://IP:port/src/news/src/1.jpg”
“/src/1.jpg” --> “协议://IP:port/src/news/src/1.jpg” -
绝对网络路径
这就是一个绝对网络路径: “协议://IP:port /src/news/src/1.jpg”
思考题:
用户输入网址: “http://192.168.6.60:8080/user/20220728/newspage”
打开了一个页面,在这个页面中的一个img的src是: “192.168.6.60:8080/src/1.jpg”
请问这个192.168.6.60:8080这个服务器会收到req.url是什么?
答:“/192.168.6.60:8080/src/1.jpg”
它真正的网址是: “http://192.168.6.60:8080/user/20220728/192.168.6.60:8080/src/1.jpg” -
本地相对根路径
思考题:
用户本地打开: “file:///c:/xx/xx/xx/index2.html”
页面中有一个img的src是: “/src/1.jpg”
它的真正路径: “file:///c” -
网络相对根路径
“/src/1.jpg”
思考题:
用户输入网址: “http://192.168.6.60:8080/user/20220728/newspage”
打开了一个页面,在这个页面中的一个img的src是: “/src/1.jpg”
请问这个192.168.6.60:8080这个服务器会收到req.url是什么?
答:“/src/1.jpg”
真正的网址: “http://192.168.6.60:8080/src/1.jpg”
静态资源托管
前端页面的一切都是静态资源,例如css,字体库,图片等等,我们统一把它们放在一台服务器上,当有用户访问的时候,就发送资源给它们
var mime=require("mime")
var url=require("url")
var querystring=require("querystring")
var http=require("http")
var fs=require("fs")
var app=http.createServer((req,res)=>{
let urlobj=url.parse(req.url)
let pathname=urlobj.pathname
if(pathname=="/"){
pathname="/index.html"
}
let path=__dirname+pathname
fs.readFile(path,(err,data)=>{
if(!err){
let type1=mime.getType(path)
res.setHeader("content-Type",type1)
res.end(data)
}
else if(pathname=="/login"){
let queryobj=querystring.parse(urlobj.query)
console.log(queryobj)
//把前端传过来的数据 去处理
res.end("hello")
}
else if(pathname=="/car"){
res.end("car")
}
else {
res.end("404 not found")
}
})
})
app.listen(8080)
浏览器是怎么加载网页的呢?
- 浏览器的地址栏,输入网址,敲回车,会请求一次服务器,服务器会返回一个数据包 就是网页代码(html格式的文本文档)
- 浏览器开始去运行解析html文本(此时还没有外部,图片,js,css,字体资源库等等)
解析时,遇到了img标签的src属性 会异步执行,开始再次网络请求服务器,服务器返回数据包(图片编码)然后渲染出来
解析时,遇到了link的href属性同样的会异步的,开始再次网络请求服务器,服务器返回数据包(css编码)然后加载
解析时,xxxx-url会异步的 开始再次网络请求服务器,服务器返回数据包(对应编码)然后加载
解析时,script-src会异步的,开始再次网络请求服务器,服务器返回数据包(对应编码)然后用js引擎去执行编码 - 所以的资源加载完毕了,才会触发window.onload