一、安装node.js
按照文件 node和egg.md 的操作进行安装,版本是v12.16.3。
1.下载node安装包
https://nodejs.org/download/release/v12.16.3/
下载——以前的版本——12.16.3
不建议安装最新版(对Windows系统有一定的要求 预览版:bug多
.zip是压缩包,需要自己解压然后各自配置 .mis安装包:一直点下一步就OK
2.退出各种杀毒软件、防火墙
把电脑中安装的杀毒软件各种防护的东西先退出,Windows自带的防火墙关闭
3.新建文件夹nodejs
在非系统盘(defg)的根盘下新建一个文件夹,命名为nodejs(这里用的F盘)
4.安装node
双击安装包,所有的选择就点下一步,只有一步就是选择安装路径不要选默认(默认路径有空格)(这里的安装路径是 F:\nodejs )
5.添加环境变量
在系统变量里面添加NODE_PATH
在Path里面添加
6.测试环境变量是否安装成功
随便打开一个文件夹,地址栏输入cmd敲回车打开DOS小黑窗
输入node -v 敲回车
输入npm -v 敲回车
输入npm i nodemon -g 敲回车
二、http模块
查看电脑本机地址:在cmd里面输入ipconfig,回车,找到第一个 IPv4,我这里是192.168.36.1
如何写一个简单的http服务器:
/*
在文件所处的文件夹打开 cmd.exe 这个软件,输入Windows的指令:
node 02-nodeinstall.js ==>node就是去环境变量中找到这个node变量指向软件,然后用 node.exe 这个软件去运行 index.js 文件
停止:ctrl+c
清屏:cls
返回上一条命令:↑
*/
// 如何写一个简单的http服务器:
// 引入node自带的模块http这个模块 可以调用函数来创建后端服务器
var http = require("http") //引入官方的http模块
// 创建一个服务器对象,回调函数不会直接运行,会在用户每次访问当前计算机的ip下的8081端口运行
var app = http.createServer((req, res) => { //req代表前端发送过来的数据包
res.end("hello 666")
})
app.listen(8081) //监听计算机的端口:min-max
http模块:
在.js文件中写入代码,然后在当前文件夹的cmd里面输入 node js文件名,回车,运行后端程序;在浏览器打开本机网址。网址栏输入192.168.36.1:8081/home(8081是自己设置的监听计算机的端口,/home是自己设置的req.url=="/home"想要跳转的网址),回车,得到如图页面:
如果8081后面没有东西,则是这样的页面:
代码如下:
var http = require("http") //引入官方的http模块
// 创建一个服务器对象,回调函数不会直接运行,会在用户每次访问当前计算机的ip下的8081端口运行
var app = http.createServer((req, res) => { //req代表前端发送过来的数据包
console.log(req.url);
if (req.url == "/home") { //在网址后面输入 /home 才运行
res.setHeader("content-Type", "text/html;charset=utf8") //配置返回给用户的数据包的数据格式和编码的类型utf8 (不设置utf8,显示的中文就是乱码) //"text/html" text/ 后面是文件类型,end()里面写的是什么就是什么类型
res.end("<h1>你好,,home 666</h1>") //给前端最后一次发送数据包 end()里面数据类型有 string buffer
} else if (req.url == "/car") {
res.setHeader("content-Type", "text/html;charset=utf8")
res.end("<h1>car 666</h1>")
} else if(req.url=="/favicon.ico"){
// 给前端发送一个小图标
} else {
res.setHeader("content-Type", "text/html;charset=utf8")
res.end("<h1>你好,你输入的网址是乱输的 404</h1>")
}
res.end("hello 666")
})
app.listen(8081) //监听计算机的端口
三、fs模块
引入fs模块:
// 引入fs模块(系统自带的) file system (文件操作系统)
var fs=require("fs");
fs.readFile("./src/alipay.png",(err,data)=>{
console.log(err,data);
}) //readFile(文件路径path, (err,data)=>{})
使用fs发送图片给前端:
var http = require("http"),
fs = require("fs"),
app = http.createServer((req, res) => { //有无数个网址
if (req.url == '/alipay.png') {
// 读取一个图片
fs.readFile("./src/alipay.png", (err, data) => {
if (!err) { //如果不是err,则执行
res.end(data)
}
})
} else {
res.end("not found 404")
}
});
app.listen(8081);
静态网址:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>07-index</title>
</head>
<body>
<h1>hello home</h1>
<p>你好,1号</p>
<p>你好,2号</p>
<p>你好,3号</p>
<p>你好,4号</p>
<p>你好,5号</p>
<p>你好,6号</p>
<p>你好,7号</p>
<p>你好,8号</p>
<p>你好,9号</p>
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F4k%2Fs%2F02%2F2109242312005c1-0-lp.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1661532277&t=9f6541312ca2c279ea732c9c0679afd8" alt="">
<p>你好,10号</p>
<p>你好,11号</p>
<p>你好,12号</p>
<p>你好,13号</p>
<p>你好,14号</p>
<p>你好,15号</p>
<p>你好,16号</p>
<img src="http://192.168.36.1:8081/src/ask.png" alt="">
<!-- http://192.168.36.1:8081/src/ask.png 绝对网络路径 -->
<img src="/src/ask.png" alt="">
<!-- /src/ask.png ==> 当前网页的网址中 http://ip:port/src/ask.png -->
<a href="/123">eb3l</a>
<p>你好,17号</p>
<p>你好,18号</p>
<p>你好,19号</p>
<p>你好,20号</p>
</body>
</html>
var http = require("http");
var fs = require("fs");
var app = http.createServer((req, res) => {
// 前端的每一次网络请求,这个函数都会重新运行一次
if (req.url == "/home") { //文本文档
fs.readFile("./07-index.html", (err, data) => {
// MIME
res.setHeader("content-Type", "text/html;charset=utf8")
res.end(data);
})
} else if (req.url == "/123") { //字符串编码
res.setHeader("content-Type", "text/html;charset=utf8")
res.end("123"); //括号里面只能是字符串或者buffer类型
} else if (req.url == "/src/ask.png") { //图片
fs.readFile("./src/ask.png", (err, data) => {
res.setHeader("content-Type", "image/png")
// res.setHeader("content-Type","image/png") //png也可以是jpg、jpeg等,看自己的图片后缀是啥
console.log(err,data);
res.end(data)
})
} else { //其他不存在的
res.end("404")
}
})
app.listen(8081)
// 热更新:更新的时候只用更新资源,服务器不用关服,js代码没有改变不用重新启动后端
四、__dirname 和 __filename
在node.js环境中,有两个全局变量:__dirname、__filename
【1】它们保存的是字符串
【2】__dirname当前js. 文件所在的文件夹的目录:绝对路径 文件夹(directory)
__filename当前js 文件的目录:绝对路径
console.log(1111111,__dirname,__filename,222222); //1111111 G:\在线学习相关\大三下\电子商务实习\h2020501\day48 G:\在线学习相关\大三下\电子商务实习\h2020501\day48\01-__dirname.js 222222
var fs=require("fs");
// __dirname更常用
fs.readFile(__dirname+"/01-__dirname.html",(err,data)=>{
console.log(err,data.toString()); //null 打印html文件里的代码
});
fs.readFile(__filename,(err,data)=>{
console.log(err,data.toString()); //null 打印这份js文件里的代码
});
五、fs模块的属性
var fs = require("fs")
1.读取文件
fs.readFile(path,(err,data)=>{})
path 填路径 可以绝对可以相对
err代表读取失败
data代表读取成功 它是一个buffer类型的数据(二进制数据流) 可以通过toString()转化为字符串
注意:res.end()方法接受 字符串或者buffer
// 【1】读取文件 buffer
// 是异步执行的
fs.readFile(__dirname + "/src/a.txt", (err, data) => {
console.log("a", data);
})
// fs.readFile(__dirname+"/src/movie.mp4",(err,data)=>{
// console.log("movie",data);
// })
fs.readFile(__dirname + "/src/recom1.jpg", (err, data) => {
console.log("recom1", data);
})
2.写入文件信息
fs.writeFile(path ,data,callback(er))
如果文件存在,该方法写入的内容会覆盖旧的文件内容,不存在就创建一个新的
path - 文件路径
data - 要写入文件的数据,可以是 String(字符串)
callback - 回调函数,回调函数只包含错误信息参数(err),在写入失败时返回。
// 【2】写入文件信息
fs.writeFile(__dirname + "/src/a.txt", "hello", function (err) {
console.log(err); //失败的原因一般有:路径不对、没有权限
})
// 创建并写入文件信息:如果文件不存在,就会创建
fs.writeFile(__dirname + "/src/b.txt", "hello6666", function (err) {
console.log(err);
})
// 如果文件夹不存在,就会报错
// fs.writeFile(__dirname+"/src1/b.txt","hello6666",function(err){
// console.log(err); //报错
// })
3.删除文件
fs.unlink(path,callback(err))
path - 文件路径
callback(err) - 删除回调函数,err错误信息
// 【3】删除文件:如果删除遇到权限问题,会删除失败
fs.unlink(__dirname+"/src/a.txt",(err)=>{
console.log(err);
})
4.以追加方式写入文件
// 【4】拼接内容到文件(以追加方式写入文件):如果文件不存在,就会创建一个
fs.appendFile(__dirname + "/src/b.txt", "马上下课", (err) => {
console.log(err);
})
fs.appendFile(__dirname + "/src/b2.txt", "马上下课", (err) => {
console.log(err);
})
5.创建目录(文件夹)
// 【5】创建目录(文件夹)
fs.mkdir(__dirname + "/src/images", (err) => {
console.log("创建目录成功");
})
6.移动/重命名文件或目录
移动/重命名文件或目录:整个功能相当于重命名一个文件/文件夹路径
fs.rename(oldPath, newPath, callback)
oldPath,原目录/文件的完整路径及名
newPath, 新目录/文件的完整路径及名;如果新路径与原路径相同,而只文件名不同,则是重命名
callback(err),操作完成回调函数;err操作失败对象
移动文件有一个bug:新路径和旧路径必须是同一个根盘
// 【6】移动/重命名文件或目录:整个功能相当于重命名一个文件/文件夹路径
// 注意:fs.rename的bug==>oldpath,newpath不是同一个根盘操作会失败
// fs.rename(oldpath,newpath,(err)=>{})
var oldpath = __dirname + "/src/b.txt"
var newpath = __dirname + "/src/a/b.txt"
fs.rename(oldpath, newpath, (err) => {
console.log(err);
})
7.拷贝
fs.copy(oldPath, newPath, callback)
oldPath, 原文件的完整路径
newPath, 新文件的完整路径
callback(err), 操作完成回调函数;err操作失败对象
拷贝文件以后两个文件都会存在磁盘中
// 【7】拷贝
var oldpath = __dirname + "/src/a/recom1.jpg"
var newpath = __dirname + "/src/images/recom1.jpg"
fs.copyFile(oldpath, newpath, (err) => {
fs.unlink(oldpath, () => {})
})
8.读取文件夹(目录)
// 【8】读取文件夹(目录)
fs.readdir(__dirname,(err,arr)=>{
console.log(err,arr); //null [ '03-fs模块.js', 'src' ]
})
最终文件目录
六、url模块
作用:可以把url网址解析为一个对象
var urlobj=url.parse(req.url)
urlobj.pathname
urlobj.query
// 专门解析url相关的功能
// var url=require("url")
// // console.log(url);
// // 把网址解析为一个对象
// var str="http://www.hqyj.com/20220728/news/page1/index.html?count=20&maxid=123456"
// var obj=url.parse(str)
// console.log(obj);
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)=>{
console.log(req.url); //"20220728/news/page1/index.html?count=20&maxid=123456"
var path=url.parse(req.url).pathname
fs.readFile(__dirname+path,(err,data)=>{
res.end(data)
})
})
app.listen(8080)
url模块和http和fs实现静态资源托管:
// var obj=url.parse(网址str) //obj.pathname obj.query
// url模块和http和fs实现静态资源托管
var http = require("http")
var fs = require("fs")
var url = require("url")
var app = http.createServer((req, res) => {
// req,res是什么? -- 前端发送给后端的网址
// 为什么要打印req.url
console.log(req.url); // "/a.txt"
var path = url.parse(req.url).pathname
if (path == "/") {
// fs.readFile(__dirname + "/src/b/index.html", (err, data) => {
// res.end(dada)
// })
path="/b/index.html"
}
fs.readFile(__dirname + "/src" + path, (err, data) => {
if (err) {
res.end("not found")
} else {
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=20&maxid=123456");
console.log(obj);
var str2=querystring.stringify({name:"jack",age:20})
var str3=JSON.stringify({name:"jack",age:20})
console.log(str2,str3);
querystring和各个模块实现静态资源托管:
// url querystring http fs一起使用
// querystring和各个模块实现静态资源托管
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 = __dirname + "/src/index.html"
}
let path = __dirname + "/src" + pathname
console.log(11111, path); //11111 G:\在线学习相关\大三下\电子商务实习\h2020501\day48\07-querystring模 块-静态网站/src/login
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); //[Object: null prototype] { pwd: '456', username: 'jack' }
res.end("hello")
} else if (pathname == "/car") {
res.end("666car")
} else {
res.end("404 not found")
}
})
})
// 监听端口
app.listen(8080)
八、各种路径
【1】本地相对路径
在这个页面写路径
"./src/recom1.jpg" 写这个路径的文件的页面是在
【2】本地绝对路径
从根盘开始写路径
"G:\在线学习相关\大三下\电子商务实习\h2020501\day48\src"
【3】相对网络路径
-- 当前页面的网址 "协议://ip:port/src/news/index.html/querystring/hash"
-- 页面内部的路径 "./src/recom1.jpg" ==> "协议://ip:port/src/news/src/recom1.jpg"
-- 页面内部的路径 "/src/recom1.jpg" ==> "协议://ip:port/src/news/src/recom1.jpg"
-- 【思考1】:用户输入网址:"http://192.168.36.1:8080/user/20220728/newspage.html?n=20"打开了一个页面,在这个页面中有一个img的src是:"./src/18.jpg",请问 192.168.36.1:8080 这个服务器会受到的 req.url 是什么?
答:"/user/20220728/src/18.jpg"
-- 【思考2】:用户输入网址:"http://192.168.36.1:8080/user/20220728/newspage"打开了一个页面,在这个页面中有一个img的src是:"./src/18.jpg",请问 192.168.36.1:8080 这个服务器会受到的 req.url 是什么?
答:"/user/20220728/src/18.jpg",它真正的网址:"http://192.168.36.1:8080/user/20220728/src/18.jpg"
【4】绝对网络路径
-- "协议://ip:port/src/news/src/recom1.jpg"
-- 【易错思考题】:用户输入网址:"http://192.168.36.1:8080/user/20220728/newspage"打开了一个页面,在这个页面中有一个img的src是:"192.168.36.1:8080/src/18.jpg",请问 192.168.36.1:8080 这个服务器会受到的 req.url 是什么?
答:"/user/20229728/192.168.36.1:8080/src/18.jpg",它真正的网址:"http://192.168.36.1:8080/user/20220728/192.168.36.1:8080/src/18.jpg"
【5】本地相对根路径
【思考】用户本地打开:file:///c:/xx/xx2/index.html 页面中有一个img的src是:"/src/18.jpg",它真正的路径:"file:///c:/src/18.jpg”
【6】网络相对根路径
-- "/src/18.jpg"
-- 【思考】用户输入网址:"http://192.168.36.1:8080/user/20220728/newspage"打开了一个页面,在这个页面中有一个img的src是:"/src/18.jpg",请问 192.168.36.1:8080 这个服务器会受到的 req.url 是什么?
答:"/src/18.jpg",它真正的网址:"http://192.168.36.1:8080/src/18.jpg"
九、mime模块
var mime=require("mime")
// console.log(mime);
var re=mime.getExtension("text/css")
var re2=mime.getType("http://20220729:8080/css/sbhkqefv.css")
// console.log(re); //css
// console.log(re2); //text/css
// url querystring http fs一起使用
// querystring和各个模块实现静态资源托管
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 = __dirname + "/src/index.html"
}
let path = __dirname + "/src" + pathname
console.log(11111, path); //11111 G:\在线学习相关\大三下\电子商务实习\h2020501\day48\07-querystring模 块-静态网站/src/login
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); //[Object: null prototype] { pwd: '456', username: 'jack' }
res.end("hello")
} else if (pathname == "/car") {
res.end("666car")
} else {
res.end("404 not found")
}
})
})
// 监听端口
app.listen(8080)
十、静态资源托管
文件夹目录
var mime=require("mime")
// console.log(mime);
var re=mime.getExtension("text/css")
var re2=mime.getType("http://20220729:8080/css/sbhkqefv.css")
// console.log(re); //css
// console.log(re2); //text/css
// url querystring http fs一起使用
// querystring和各个模块实现静态资源托管
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
// "http://192.168.36.1:8080/index.html"
// "http://192.168.36.1:8080/imgages/recom1.jpg"
if (pathname == "/") {
pathname = __dirname + "/src/index.html"
}
let path = __dirname + "/src" + pathname
console.log(11111, path); //11111 G:\在线学习相关\大三下\电子商务实习\h2020501\day48\07-querystring模 块-静态网站/src/login
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); //[Object: null prototype] { pwd: '456', username: 'jack' }
res.end("hello")
} else if (pathname == "/car") {
res.end("666car")
} else {
res.end("404 not found")
}
})
})
// 监听端口
app.listen(8080)
十一、网页的加载流程
浏览器是怎么加载网页的?
1.1 浏览器的地址栏 输入的网址,敲回车会请求一次服务器,服务器会返回一一个数据包就是网页代码(html格式的文本文档)
1.2 浏览器开始去运行解析htmL文本(此时还没有外部css图片、JS、字体库资源、css、)
1.2.1 解析时,遇到了img标签的src属性 会异步的 开始再次网络请求服务器,服务器返回数据包(图片编码),然后道染出来
1.2.2 解析时,遇到了link-href 会异步的 开始再次网络请求服务器, 服务器返回数据包(css编码),然后加载
1.2.3 解析时,xxx-urL会 异步的 开始再次网络请求服务器, 服务器返回数据包(对应编码),然后加裁
1.2.4 解析时script-src会 异步的 开始再次网络请求服务器,服务器返回数据包(js编码),然后用js引擎去执行编码
1.3 所有资源加载完毕了,才会触发window. onload
十二、模块化
1.模块化语法--require
模块化:把一系列相类似功能,封装到一个模块中,然后供使用
nodejs环境中的全局函数:require() 在浏览器中并不能用这个,因为没有
引入前端的js文件要用import;后端运行时,引入第三方js文件,就用require(),也可以用import(es6语法) 前者可以懒加载,后者不可以懒加载
nodejs中有3种模块:
【1】内置(核心)模块 nodejs安装时,自身就安装好了的模块
核心模块就是 Node 内置的模块,需要通过唯一的标识名称来进行获取。每一个核心模块基本上都是暴露了一个对象,里面包含一些方法供我们使用。一般在加载核心模块的时候,变量(或常量)的起名最好就和核心模块的标识名同名。
【2】第三方模块,需要下载才能使用,下载指令:npm i xxx,xxx是需要使用的模块
【3】自定义模块,我们自己封装的函数
文件夹
【myquerystring.js】
module.exports={
tool(){
console.log(66666);
}
}
【001-模块化语法.js】
// nodejs中有3种模块
var fs=require("fs") //内置(核心)模块 nodejs安装时,自身就安装好了的模块
var mime=require("mime") //第三方模块,需要下载才能使用,下载指令:npm i mime (在cmd里面输入)
var myquerystring=require("./myquerystring.js") //自定义模块,我们自己封装的函数
myquerystring.tool();
console.log(myquerystring.url); //undefined
查找模块是否存在:
require("fs1") ==> 去当前项目中的【node_modules文件夹】中找【fs1文件夹】中的【package.json】中的【main字段】对应的路径,然后引入
如果没有就去node的安装包中的全局安装路径中找 node_global
如果还是没有找到,就去核心库
如果还是找不到就报错
package.json是项目的配置文件
2.模块化语法2
最初状态
【003-npm和 package.json\index.js】
var mime=require("mime") //第三方模块
// 自定义模块my1
var my1=require("./my1.js")
console.log(my1);
// 自定义模块my2--自己新建一个my2文件夹然后仿照mime添加配置文件,或者从npm社区下载包
var my2=require("my2")
console.log(my2);
【1】下载第三方模块mime
在小黑窗(cmd)输入 npm i mime,回车等待运行结束得到一个文件夹 node_modules 和JSON文件 package-look.json
【2】创建自定义模块my1
在 003-npm和 package.json 文件夹中新建一个 my1.js 文件,在 my1.js 中写入需要的代码
【3】创建自定义模块my2(如何添加配置文件)
在 node_modules 文件夹中新建一个 my2 文件夹(实践操作是不会这么做的),在 my2 中新建 index.js 文件
在 node_modules 文件夹下的 my2 文件夹的 cmd小黑窗 输入 npm init ,回车等待程序运行,后续全部回车,直到运行结束,得到JSON文件 package.json(配置文件)
在 my2文件夹 里面就可以实现项目的模块化,在 index.js 里面引入其他文件,如 b.js,新建文件 b.js,在文件里输入代码,可以实现 b.js 的导出,一个引一个
【003-npm和 package.json\node_modules\my2\index.js】
// 项目的入口:index.js
var b=reiure("./b.js")
module.exports={ //导出
a:1000,
b
}
【003-npm和 package.json\node_modules\my2\b.js】
module.exports={
c:80
}
在 003-npm和 package.json 文件夹下打开cmd,运行 index.js 文件
3.npm和package.json
做项目的第一步:生成配置文件 package.json
在 003-npm和package.json文件夹 新建一个文件夹,使用英文命名为 app,在app下打开cmd,输入命令 npm init -y 回车得到运行完毕,生成配置文件 package.json
在 文件夹app 中新建 index.js文件 , 在app下打开cmd,输入命令 npm i mime --save 将mime模块的相关文件下载到当前文件夹
运行 index.js文件 的方法:
【1】在app的cmd输入 node index.js;
【2】在package.json 中添加一段代码 "dev":"node index.js",在app的cmd输入 npm run dev
使用【2】的目的:简化代码
ps:交项目的时候,文件不要node_modules文件夹,接收文件的人直接用 npm i 可以下载所有模块
4.npm模块
小黑窗的指令:
i和install是一样的
【1】把模块x1 x2 x3这个三个模块下载到全局安装路径
npm i 模块名字x1 模块名字x2 模块名字x3 -g
【2】把模块x1 x2 x3这个三个模块下载到项目安装路径(就是当前项目内部 的node_modules)
npm i 模块名字x1 模块名字x2 模块名字x3 或者
npm i 模块名字x1 模块名字x2 模块名字x3 --save
【3】下载了第三方模块后 npm会在项目配置文件中的依赖项中写入下载的第三方模块名和版本
等后面学习完webpack就懂了
依赖项
npm i x1 --save
npm i x1 --save-dev
npm i x1 -S
npm i x1 -D
npm i 去项目的配置文件中找到依赖的包 全部下载
npm run dev 去项目的配置文件中找到scripts字段 运行里面的dev指令
5.package.json
项目的配置文件 用于记录整个项目的一些信息
项目名==>项目的名字
作者信息:
"scripts":{"dev":"node index.js"} 启动指令 主要用于小黑窗的npm启动 npm run dev
"dependencies" 项目依赖
十三、node.js介绍
【0】代码:语言
c/c++ windows linux
swift object-c ios
java 安卓
html/css/js 浏览器
javascript node.js
【1】node.js是什么?
-- 是一个基于Chrome-v8设计的单线程的基于事件驱动的非阻塞I/O模型的一个js运行环境
-- 事件驱动==>回调函数
【2】它有什么特点?
-- [1] 单线程 ==> node.js的主线程,是程序员写的这个线程,这个线程的代码是v8在运行js代码
-- [2] 非阻塞I/O模型 ==> I/O 耗时操作(写入和读取的功能),让计算机的多核发挥功能,同时执行任务
-- [3] 基于事件驱动的 ==> 回调函数,让异步任务去子线程中执行,然后注册一个事件,任务执行完毕以后,就回到主线程执行回调函数
-- [4] 模块化 ==> 把功能社区按照模块来封装,方便扩展、维护管理,更有利于开发大型项目;npm社区node.js的模块化社区,是全世界最大的模块市场,2018年被微软收购
typescript==>javascript
【3】node.js是单线程还是多线程?为什么是单线程,还可以不阻塞?
【4】目前node.js的地位?
-- node是一个开源的免费的环境,性能好速度快,资源占用小,但是它不安全
【5】创始人:Ryan
2007年,兼职敲代码,外部
思考怎么把前端和后端统一 c/ruby等等都失败了
2008年,谷歌发布v8引擎
2010年,微软的技术高管离职了,全职加入node的维护
后来,技术高管离开了node,去研究人工智能了
2020年,他deno环境,可以直接运行ts
十四、AJAX:网页局部刷新数据技术
前端刷新页面有两种技术:
【1】整页面刷新:跳转到一个新的网页html
【2】局部刷新:用js去做网络请求,然后将得到的数据,动态地渲染的DOM ==> AJAX技术
使用AJAX的步骤:
【1】创建网络请求(AJAX)对象
let xhr = new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP");
【2】配置(建立)连接信息:true--是否异步请求,默认为true
xhr.open("GET", `http://192.168.36.1:8080/ajax1?name=karen&count=20`, true);
或者是:
xhr.open("GET", `/ajax1`, true);
【3】发送网络请求
xhr.send();
【4】等待(监听网络状态的变化)
//readyState==>1 2 3 4
xhr.onreadystatechange = function () {
console.log(xhr.readyState, 000);
【5】xhr.readyState==4 代表网络请求收到数据包
【6】解析数据
【7】使用数据DOM操作局部渲染刷新页面
【index.html】
<body>
<h1>首页页面</h1>
<!-- 当前页面的网址:http://192.168.36.1:8080/index.html -->
<!-- 这两个的网址都是:http://192.168.36.1:8080/images/recom1.jpg -->
<img src="http://192.168.36.1:8080/images/recom1.jpg" alt="">
<img src="images/recom1.jpg" alt="">
<a href="http://192.168.36.1:8080/ajax1">看页面Ajax</a>
<button onclick="load1()">网络请求:ajax请求数据</button>
<div style="width: 200px;height:200px;background-color: antiquewhite;"></div>
<script>
/*
前端刷新页面有两种技术:
【1】整页面刷新:跳转到一个新的网页html
【2】局部刷新:用js去做网络请求,然后将得到的数据,动态地渲染的DOM ==> AJAX技术
*/
function load1() {
console.log(6666);
// AJAX技术
// window.XMLHttpRequest
let xhr = new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP"); //【1】创建Ajax对象
xhr.open("GET", `http://192.168.36.1:8080/ajax1?name=karen&count=20`, true); //【2】配置连接信息
// xhr.open("GET", `/ajax1`, true); //【2】配置连接信息 true--是否异步请求,默认为true
xhr.send(); // 【3】发送网络请求
//【4】等待(监听网络状态的变化)
// while(xhr.readyState!=4){ //这是同步思想,会阻塞,所以不好
// }
xhr.onreadystatechange = function () {
console.log(xhr.readyState, 000);
if (xhr.readyState == 4 & xhr.status ==
200) { //xhr.readyState==4 代表网络请求收到数据包 xhr.status==200 代表网络请求成功,200是状态码
console.log(xhr.responseText, 111);
} else if (xhr.readyState == 4 & xhr.status == 404) { //xhr.status==404 代表网络请求成功,业务数据失败
console.log(xhr.responseText, 222);
// 解析数据
var obj = JSON.parse(xhr.responseText)
console.log(obj);
//7.使用数据DOM操作局部渲染刷新页面
// div.innerHTML = obj.xx.xx
}
}
}
</script>
</body>
【index.js】
var http = require("http")
var fs = require("fs")
var url = require("url")
var querystring = require("querystring")
var mime = require("mime")
var app=http.createServer((req,res)=>{
let pathname=url.parse(req.url).pathname
fs.readFile(__dirname+"/src"+pathname,(err,data)=>{
if(!err){
res.setHeader("content-Type",mime.getType(pathname)) // mime.getType(pathname) 把pathname转换成mime类型
res.end(data)
}
else if(pathname=="/ajax1"){
res.writeHead(404,{"content-Type":"text/json"}) //状态码为404
res.end('{"name":"karen","age":20}')
} else if(pathname=="/ajax2"){
res.writeHead(404,{"content-Type":"text/json"}) //状态码为404
res.end('{"name":"karen2","age":20}')
} else if(pathname=="/login"){
res.writeHead(404,{"content-Type":"text/json"}) //状态码为404
res.end('{"name":"karen3","age":20}')
}
else{
res.end("404 not found")
}
})
})
app.listen(8080);