node

node

node.js 不是一门新的语言,是不熟在浏览器的一个工具;给JS提供运行环境的;就像一个谷歌浏览器一样;基于V8引擎的;

开发一个完整的项目,需要前端,还需要后端;后端的代码是运行在服务器上的;通过客户端发送http请求,去请求服务器的资源,把前端的代码拉取到客户端,浏览器进行渲染,【html css】
浏览器可以解析JS,JS在浏览器的环境下运行,一旦遇到ajax,会想后端发送请求,后端会接收到请求,会处理数据,最终响应给客户端;

node:不是在服务器,JS就可以运行在服务器上;
JS是一门全栈开发语音;
JS在node环境下运行的语法,运行的特点;
node.js:
1、属于单线程的异步;事件驱动;
2、事件驱动的非阻塞I/O 操作,轻量且高效
3、npm 包管理器 https://www.npmjs.com/ 全球最大的生态开源库
npm 是伴随node安装,也会安装好npm命令

npm install jquery

node中的模块(三类模块):就是e一个JS,内置了一些方法供使用,在node中一个JS就是一个模块;而且node天生自带模块化
1、核心模块:是安装nod时,把这些都安装到全局
2、自定义模块:自己实现的模块, require解决了模块的入口问题,module.exports=exports={fn:fn}
3、第三方模块:npm;
fs模块 :读写文件的模块
url模块:处理url地址的模块
**运行:用node.js运行 或者 WebStorm中的js文件,右键run**

  • 如果JS在浏览器运行,那么浏览器会给js提供一个全局的window环境;
  • 如果要是在服务器上运行,服务器会给当前js提供global环境,this是空对象
    node 是天生自带模块化;如果是一个JS文件那么会在当前JS文件最外面套一个自执行函数;
    let fs = require('fs'):给一个JS文件引进一个JS文件
    let fs = require('./1.js'):如果是同级目录,需要加上./,在node的环境下,可以省略,js或者.json
    默认return module.exports
       (function(exports,module,require,__dirname,__filename){
       console.log(this)==> {}
           exports---> 导出{};
            module---> 模块{好多键值对}
          __dirname--->当前文件父级文件的绝对路径
          __filename--->当前文件的绝对路径
       })()

AMD、CMD、common.js 规范
npm 第三方包管理器,以后大家会在npm上下载对应的组价,框架,或者类库,通过命令行下载;
文件右键 show in explorer
父级文件名字不要有汉字;可以是字母和数字组成;
npm init -y:初始化配置文件;当前项目会多一个package.json
package.json:记录当前项目下载的类库,组件
npm install jquery --save-dev:将模块下载到当前项目下,并且在package.json进行记录,生成一条开发环境的依赖项;
如果当前项目是第一次下载模块,会自动生成一个node_modules文件夹,文件夹存放了下载的模块
npm install vue --save-dev:可以写版本号(开发环境,上线的时候不需要;譬如:less)
npm install jquery@1.11.3 --save(生产环境,上线时候需要)
安装的模块和当前模块的版本,默认下载的是最新的版本;

如果下载的相同的模块,下一次会把上一次的覆盖掉;之前的版本已经被卸载了
npm install :把packages里面记录的文件下载到本地

核心的模块;当安装之后,当前模块已经自动安装好
fs模块:文件操作模块;一般用于读写文件的,

  • 1、先导入模块
    let fs = require('fs')
  • 2、异步读取一个文件
    fs.readFile('./1.js','utf8',function(err,data){
    err:代表的是错误信息
    data:代表读取文件的内容;默认的编码格式buffer 类型,butter:0-9 a-f十六进制
    })
  • 3、同步读取文件(path,options);同步读取文件内容,把读取的内容放到当前方法的返回值,不需要回调函数
    let con = fs.readFileSync('路径','utf8')
    console.log(con);

修改文件:
3、writeFile(异步;是把原有的内容覆盖掉)参数:path:路径、data:写入的数据、option:编码格式、callback:回调函数
4、writeFileSync(同步)参数:path:路径、data:写入的数据、option:编码格式

    fs.writeFile('./12.txt','马上毕业了','utf8',function(err){
       err:错误信息
       console.log(1)
       当把数据写入成功之后,会调用这个函数
})

buffer.from:把字符串转换成buffer类型
toString:把buffer类型转成字符串
fs.appendFile:向文件的末尾,新增内容
fs.appendFileSync:同步

   let fs = require('fs');
    fs.appendFile('./4.txt','789','utf8',function (err) {
        console.log('新增');
    })
image.png

image.png

https://blog.csdn.net/p358278505/article/details/78094542
https://www.jianshu.com/p/b583e6bc6139
改变npm镜像npm config set registry 网址
https://blog.csdn.net/landl_ww/article/details/79149461
npm config set registry https://registry.npm.taobao.org

npm config list ## 查看刚才的配置是否生效

http

http :模块:用于服务器监听服务;

  let http = require('http');
//console.log(http);
http.createServer(function (req,res) {
    //req:request:代表的是请求体中的信息  
    //res:response:代表响体的信息
    //res.end:把后端查找的内容响应给客户端;客户端可以接收到后端传输的数据;响应中文为乱码
    res.end(123);
    //当客户端请求一次,这个函数会执行一次
    console.log('你访问了吗');
}).listen(8000,function () {
    //用一个端口号监听这个服务
    console.log('监听成功');
});
/*
 http.createServer :创建一个服务
 listen:用一个端口号监听这个服务
一个端口号只能被一个服务监听;如果多个服务监听同一个端口;那么会出现端口被占用
let http = require('http');
let url = require('url');
http.createServer(function (req,res) {
    //当客户端请求几次,执行几次
    //req:请求信息   res:响应信息
    //console.log(req);
    console.log(req.url);

    //url.parse:把req请求体中的url进行处理,返回一个对象,包含pathname,
    console.log(url.parse(req.url,true));
    //true:query的属性值是一个对象;存储了地址中的参数;以键值对形式存储;默认是false,query的属性值是一个字符串
    let {pathname} = url.parse(req.url);
    res.end({pathname});
}).listen(8001,function () {
   //这个函数等监听成功之后,立即执行一次
    console.log('监听成功');
});

let http = require('http');
let url = require('url');
let fs = require('fs');
http.createServer(function (req,res) {
    let {pathname} = url.parse(req.url);
    fs.readFile('.'+ pathname,'utf8',function (err,data) {
        res.end(data);
    });
}).listen(8002,function () {
    console.log('监听成功');
});
//打开浏览器的时候需要些路径
let http = require('http');
let url = require('url');
let fs = require('fs');
http.createServer(function (req,res) {
    //当浏览器接收到服务器响应回来的内容后,不知道服务器响应回来时什么类型;如果服务器通过响应头,通知浏览器,返回的是什么类型;
    //所以在响应回去之前,提前设置响应头;
   res.writeHead(200,{'Content-Type':'text/plain;charset=UTF-8'});
    res.setHeader('Contet-Type','text/plain;charset=UTF-8');
    //区别,writeHead可以添加状态码
    res.write('你是不是傻');
   res.end('帕金森')

}).listen(8002,function () {
    console.log('监听成功');
});

浏览器通过url向服务器发送请求,服务器接收到请求,服务器会根据你的路径,它要找到对应的文件,然后服务器把文件读出来,然后把文件的数据通过http;对于node来说,通过响应res的end方法返回过去;返回过去一个字符串,浏览器接收到之后,把得到的数据进行解析;但是在解析过程中,会遇到link的href,img的src,script的scr;客户端会继续向服务器发送请求;服务器的监听函数会再次被触发。

let  http = require("http");
let fs = require("fs");
let url = require("url");
// 常用mine 类型;通知浏览器按照什么类型解析文件;
//  css  : text/css
//  html : text/html
//  jpg : image/jpeg
//  png : image/png
//  js : application/javascript
//  json : application/json
//  text : text/plain;

//  html: 浏览器会默认按照HTML进行解析文件;

http.createServer(function (req,res) {
    let {pathname} = url.parse(req.url);
    // 以.jpg 结尾的字符;
    let  reg = /\.png$/;
    if(reg.test(pathname)){
        res.setHeader("Content-Type","image/png");
        fs.readFile('.'+pathname,function (err,data) {
            console.log(data);
            res.end(data);
        });
        return;
    };
    // 如果是图片;把图片读成buffer类型;不需要是utf8 格式;
    fs.readFile('.'+pathname,"utf8",function (err,data) {
        res.end(data);
    });

}).listen(8080);

let http = require('http');
let url = require('url');
let fs = require('fs');
let mime = require('mime');
//mime:第三方模块,需要下载 mime 有个getType的方法;只需要把路径传给这个方法,那么就会返回当前文件对应的content-type类型
/*
npm init -y
npm install mime --save
*/
http.createServer(function (req,res) {
  let {pathname} = url.parse(req.url);
    res.setHeader('Content-Type',mime.getType(pathname));
    fs.readFile('.'+pathname,'UFT8',function (err,data) {
       res.end(data)
    });
    console.log(mime.getType(pathname));
}).listen(8888,function () {
    console.log('监听成功');
});

let  http = require("http");
let fs = require("fs");
let url = require("url");
let mime = {
    ".css":"text/css",
    ".html":"text/html",
    ".json":"application/json",
    ".png":"image/png"
}

http.createServer(function (req,res) {
    let {pathname} = url.parse(req.url);
    // 根据pathname的后缀名;去mime对象中去获取对应的content-type;
    let reg = /\.(\w+)$/;
    let name = reg.exec(pathname)[0];//[ '.html', 'html', index: 7, input: '/index1.html' ]
    res.setHeader("Content-Type",mime[name]);
    fs.readFile("."+pathname,function (err,data) {
        res.end(data);
    });
}).listen(8888,function () {
    console.log("监听成功");
});
http.createServer(function (req, res) {
    let {pathname} = url.parse(req.url);
    //fs.stat:验证当前路径是否存在
    fs.stat('.' + pathname, function (err, stats) {
        console.log(err);// 如果路径是错误的;那么err是一个对象;如果路径是正确的结果为null
        if (err) {
            res.statusCode = 404;
            res.end(`${pathname}is not found`)
        } else {
            //stats.isFile:验证是否是一个文件的方法;如果是文件返回true;不是返回false
            if (stats.isFile()) {
                res.setHeader('Content-Type', mime.getType(pathname));
                fs.readFile('.' + pathname, 'utf8', function (err, data) {
                    res.end(data)
                });
            }
            else {
                res.setHeader('Content-Type', 'text/html');
                fs.readFile('./index.html', 'utf8', function (err, data) {
                    res.end(data)
                })
            }
        }
    });
    console.log(mime.getType(pathname));
}).listen(8888, function () {
    console.log('监听成功');
});

let  http = require("http");
let fs = require("fs");
let url = require("url");
let mime = {
    ".css":"text/css",
    ".html":"text/html",
    ".json":"application/json",
    ".png":"image/png",
    ".js":"application/javascript"
};

http.createServer(function (req,res) {
    let {pathname} = url.parse(req.url);


   // fs.stat  : 验证当前路径是否存在
   fs.stat("."+pathname,function (err,stats) {
       //console.log(err);
       // 如果路径是错误的;那么err是一个对象;如果路径是正确的,结果就是null;
       if(err){
           res.statusCode = 404;
           res.end(`${pathname} is  not  found`);
       }else{
           // stats.isFile : 验证是否是一个文件的方法;如果是文件,返回true;不是返回false;
           //console.log(stats.isFile());
           if(stats.isFile()){
               let reg = /\.(\w+)$/;
                let name = reg.exec(pathname)[0];
               //console.log(name);
               console.log(mime[name]);
               res.setHeader("Content-Type",mime[name]);
               console.log(pathname);
               fs.readFile("."+pathname,function (err,data) {
                    res.end(data);
                });
           }
           // 如果是文件夹,则返回true;
           //console.log(stats.isDirectory());
           if(stats.isDirectory()){
               fs.readFile("./index.html",function (err,data) {
                   res.end(data);
               });
           }
       }
   })
}).listen(8888,function () {
    console.log("监听成功");
});

前后端交互

cmd --> npm init -y --> npm install express --save

// express 是node的一个框架;用于处理server,请求,路由等问题;让后端的代码更加清晰;
// express是node 的第三方模块;
let express = require("express");
//console.log(express);// 函数;
let  app = express();// express 执行相当于http中createServer执行;
/*app.all("*",function (req,res) {
    console.log(1000);
    res.send("789")
});*/
app.param('id',function(req,res,nex()){
//app.param:拦截,拦截所有有id的路由,主路径不一样没关系,next是一个函数,可以让拦截的函数继续向下执行,并且可以设置响应头
  req.eat = function(){
   console.log('吃西瓜')
}
  console.log(1);
  next()
})
// app.listen : 监听一个端口,当端口监听成功之后,会触发回调函数;
app.get("/login/:id/:name",function (req,res) {
req.eat()//可以执行,因为next()
    // req: 请求体信息  res: 响应信息;
    //console.log(1);
    /*console.log(req.query);// 所有参数
    console.log(req.url);// 路径+ 参数
    console.log(req.path);// 路径
    console.log(req.params);// 会根据当前的路由和get中的第一个参数,然后进行匹配程一个对应的对象,动态路由/:id的参数等 输出个对象
    console.log(req.header);
    console.log(req.hostname);// 代表当前请求的域名;
    console.log(req.method);// 请求方式 get  post  put  delete
    console.log(req);*/
    //console.log(res);
    res.send("登录")
});
app.post("/register",function (req,res) {
    //res.setHeader("Content-Type","text/plain;charset=UTF-8")
    res.send("注册");
});
// app.get  app.post : 只能接收到对应的请求方式的请求;浏览器的url默认是get请求;
// app.all : 不管是什么类型的请求方式;都会触发这个路由和回调函数;
app.all("/order",function (req,res) {
    res.send("123456");
});
// 如果all中路径以“*”;它可以匹配所有的路径;只要发送相应的请求,都会被拦截住;
// 如果把这个all放在所有路由的最上面,会先匹配成功,那么下面路由即便匹配成功,都不再执行;
app.all("*",function (req,res) {
    console.log(1000);
    res.send("789")
});
app.listen(8888,function () {
    console.log("启动成功")
});

express

// 中间件 : 可以访问请求对象,可以访问响应对象;
// 如果在中间件中没有终结请求,必须通过next把控制权交给下一个中间件,请求将处于请求状态;
let express = require("express");
let app = express();
// 中间件一般都会放在路由的最上端;可以处理请求对象req,还可以处理响应对象;
// 一般用于处理各个请求的公共部分;
app.use(function (req,res,next) {
    // 中间件,只要访问,就会被触发;这个函数;
    console.log(1);
    req.sleep = function () {
        console.log("睡觉的发红包");
    }
    next();// 调用下一个中间件
});
app.use(function (req,res,next) {
    console.log(100);
    res.send("你很帅!")
});
// 错误处理中间件;四个参数;
// 四个参数中next虽然不需要执行,但是一定要有;
app.use(function (err,req,res,next) {
   res.status(500).send("something broke!")
});
app.get("/login",function (req,res) {
    console.log(2);
    req.sleep();
    res.send("登录");
});
app.get("/register",function (req,res) {
    console.log(6);
    req.sleep();
    res.send("注册")
});
console.log(3);

app.listen(8090,function () {
    console.log("启动成功");
});