node基础知识
node在真实项目中的应用
webpack基于node环境 用nodejs的语法合并压缩打包

js放到客户端浏览器中执行
放到服务器端运行:java因为jdk php因为tomcat c#因为有.net framework

项目架构1:中小型项目-基于nodejs构建全栈

项目架构2:大型项目

其他作用:
客户端和nodejs在同一个域下,实现跨域传输

项目架构3

node和浏览器的区别
文件的读写
I/O:指的是对文件的读写
I:写
O:读

window & global*
window提供的内置属性和方法:
- navigation
 - location
 - alert
 - window.open / window.setTimout / window.setInterval
 - window.getComputedStyle / window.requestAnimationFrame
 - JSON.parse / JSON.stringify
 
node环境:
- process
 - buffer
 - setImmediate
 -  

 
 
this
文件中的this是当前模块


比如jQuery中区分了node和浏览器

复习和加深npm的使用
npm i

开发和生产依赖
webpack:合并压缩打包
比如less:部署到服务器上的时候 需要less吗?不需要了。部署到的是css
axios:开发/生产都需要
生产依赖:开发需要,生产也需要
开发依赖:只有开发需要

全局 & 本地
全局:为了用命令
本地:require进来导入到文件中使用

环境变量*

process.env env存储的是node的全局环境变量

commonjs模块规范
模块管理机制
一个模块一定有导入/导出,创建和导入导出
node中都是按模块按规定的

核心模块
qs:把对象转换成x-www-form-urlencoded格式

node是基于commonjs模块管理思想,如何创建和导入/导出模块

node中的模块管理
每创建一个js就是创建一个模块
其实之前讲的:其实每一个单例模式就是一个单独的模块

- 互不冲突
 - module.exports 暴露给外部使用的
 

创建:创建一个js就是创建一个模块
导出:module.exports
导入:require
调取模块:相当于把模块中的js代码从上到下执行了一遍

例子:

function sum(){
    let total=0;
    total=[].reduce.call(arguments,(total,item,index)=>{
       total +=item;
       return total;
    },0)
    return total;
}
// console.log(sum(1,2,3,4,5))
module.exports={
    sum
}
 
    
    
   const a=require('./a')
function avg() {
    let sum=0,max=Math.max(...arguments),min=Math.min(...arguments);
    sum=a.sum(...arguments)
    sum-=max;
    sum-=min;
    return sum/(arguments.length-2);
}
// console.log(avg(1,2,3,4,5))
module.exports={
    avg
}
 
    
    
    
   const {avg}=require('./b')
console.log(avg(1,2,3,4,5));
 
    
   
fs模块中的方法

fs:提供大量方法赋予js在node环境下有操作文件的能力
node单线程异步:提供的大部分都是异步

fs.readdir()
回调函数机制,即事件驱动方式
相对或绝对路径
相对:./ 或者 ../
绝对:带磁盘符

读取文件*
buffer:默认读到了文件流。buffer涉及到进制转换、流那些知识点,node高级知识点。类似于进制编码的格式。


富媒体资源文件:图片、音视频等
图片:不是json、html格式文件有自己的代码,是通过自己的机制组合起来。
文件有2种:
- 自己创建一个文件,自己写内容写代码的,通过utf-8去读。
 - 富媒体用buffer去读。
 


拷贝文件

fs.readFile
fs.writeFile
fs.unlink // 删除
fs.copyFile
fs.appendFile
fs.readdir
fs.mkdir
fs.rmdir
封装成promise版
在executor中执行一个异步操作,通过resolve或reject 来通知then执行还是catch执行

路径问题
以你执行node命令的目录为根目录,而不是以你文件的目录
开发都用绝对路径
__dirname:当前模块所在的绝对路径
path.resolve()
获取的是:当前node执行时所在的目录,作为当前根目录的绝对路径

const fs=require('fs');
// function readFile(pathname) {
//     return new Promise(((resolve, reject) => {
//         let encoding='utf8'
//         // 富媒体资源不用utf8编码
//         if(/\.(png|jpg|jpeg|mp3|mp4)$/.test(pathname)){
//             encoding=null;
//         }
//         fs.readFile(pathname,encoding,(err,result)=>{
//             if(err) {
//                 return reject(err)
//             }
//             resolve(result)
//         })
//     }))
// }
const fileObj={}
['readFile','readdir','mkdir','rmdir','unlink'].forEach(item=>{
    fileObj[item]=function (pathname) {
        let encoding='utf8'
        // 富媒体资源不用utf8编码
        if(/\.(png|jpg|jpeg|mp3|mp4)$/.test(pathname)){
            encoding=null;
        }
        // pathname=path.resolve(pathname)
        return new Promise((resolve, reject) => {
            let callback=(err,result)=>{
                if(err) return reject(err)
                resolve(result)
            }
            if(item==='readFile'){
                encoding=callback;
                callback=null;
            }
            fs[item](pathname,encoding,callback)
        })
    }
})
module.exports={
    readFile
}
 
    
   基于fs完成css合并压缩*


fs的IO操作:文件或文件夹的增删改查
const {readFile,readdir}=require('./promiseFile')
const path=require('path');
const fs=require('fs');
const less=require('less')
async function readCss(){
    let results= await readdir(path.resolve(__dirname,'./css'))
    results=results.filter(filename=>/\.css/.test(filename))
    results=await Promise.all(results.map(filename=>readFile(path.resolve(__dirname,`./css/${filename}`))))
    let cssContent=results.join('')
    // 写入total.css
    fs.writeFile(path.resolve(__dirname,'./dist/total.css'),cssContent,()=>{})
    // 压缩css
    less.render(cssContent,{compress:true},(err,{css})=>{
               fs.writeFile(path.resolve(__dirname,'./dist/total.min.css'),css,()=>{})
    })
}
readCss()
 
    
   URL和HTTP模块
协议默认端口号
http:80
https:443
ftp:21
http:
创建服务,接受客户端请求,给客户端返回结果。
输入网址按下enter键:
域名解析->dns解析->tcp3次握手->发请求 服务器上有一个服务接收请求。如IIS nginx
返回结果->客户端渲染-> 断开tcp连接

0-65535

- http.createServer
 - server.listent(80,...)
 
createServer 回调:有请求过来时
const http=require('http')
let server=http.createServer((req,res)=>{
    res.end('hello world')
})
server.listen(8080,()=>{
    console.log('server is listening on port 8080!!!')
})
 
    
    
   可能返回的资源文件路径

- 根据suffix区分资源路径和数据接口
 - 富媒体走buffer 不按charset=utf8
 
const http=require('http')
const path=require('path');
const url=require('url');
const mime=require('mime');
const  {readFile} =require('./promiseFile.js')
let server=http.createServer((req,res)=>{
    // res.end('hello world')
    let {url:requestUrl}=req;
    let {pathname}=url.parse(requestUrl);
    pathname=path.resolve(__dirname,`./static${pathname}`)
    const suffixReg=/\.(\w+)$/,richReg=/\.(png|jpg|jpeg|mp3|mp4)$/;
    let suffix=suffixReg.test(requestUrl)?suffixReg.exec(requestUrl)[1]:null;
    let encoding=richReg.test(requestUrl)?'charset=utf8':'';
    if(suffix){
        readFile(pathname).then(result=>{
            res.writeHead(200,{
                'Content-Type':`${mime.getType(suffix)};${encoding}`
            })
            res.write(result);
            res.end()
        }).catch(()=>res.end('not found'))
    }
})
server.listen(8080,()=>{
    console.log('server is listening on port 8080!!!')
})
 
    
   


















![[SUCTF 2019]EasySQL](https://img-blog.csdnimg.cn/6eb0c11911a14dd1828579fdb3b925f3.png)