Node.js个人笔记

Node.js

是一个基于Chrome-v8的一个js运行环境
是一个基于Chrome-v8设计的单线程的,基于事件驱动的非阻塞I/O模型的一个js运行环境

特点:
单线程
node.js的主线程,是程序员写的,整个线程的代码是v8在运行js代码

非阻塞I/O(写入,读取)模型
让计算机的多核发挥功能,同时执行任务

基于事件驱动 --回调函数体现的
把任务添加到事件池中,让异步任务去子线程中执行,然后注册一个事件,任务执行完毕以后,就回到主线程执行回调函数

模块化
    把功能按照模块来封装 方便拓展,维护管理,更有利于开发大型项目
// npm 社区 nodejs的模块化社区,是全世界最大的模块市场 2018年被微软收购

模块 :把一系列相同类型的功能,封装到相同的模块中

__dirname:当前服务器的文件夹路径
__filename:当前服务器的文件

http:require("http)

createServer((req,res)=>{
res.end(string) // 给前端返回的数据包,返回的是字符串
}) 创建一个服务器,每次访问监控的服务器都会调用一次回调函数
listen(index) index监控的端口号

fs模块:require(“fs”)

readFile(url,cb) 读取文件
writeFile(url,text,cb) 覆盖文件内容,也可以创建文件并覆盖内容
unlink(url,cb) 删除文件
appenFile(url,cb) 拼接内容到文件,相当于添加内容到文件中,没有文件则创建文件
mkdir(url+name,cb) 创建文件夹
rename(oldpath,newpath,cb) 将旧路径的文件(夹)移到新的文件夹里面,也可以重命名名字 oldpath,newpath不是同一个根盘操作会失败(c盘移动到d盘失败)
copyFile(oldpath,newpath,cb) 拷贝文件,把旧路径文件拷贝放到新路径的地方
readdir(url,cb) 读取目录的所有的名字

网址:URL
协议 + 域名 + pathname(路径) + querystring(查询字段) + hash(这个不会发送给后端)

URL模块:require(“url”)

parse(urlString) 返回对象,把地址字符串剪辑成一个对象
obj.pathname 请求的网址路径 => obj表示字符串剪辑后返回的对象
obj.query 网址的查询字段

querystring模块:require(“querystring”)
常用于剪辑前端发送过来的网址中的查询字段
parse(string) 将字符串剪辑成对象并返回这个对象,返回对象有n个对象看网址中query字符串有多少对数据
stringfy(obj) 把对象转为queryString字符串

mime模块:require(“mime”) 第三方模块需要下载:npm i mime

getType(“txt”) 返回其类型和后缀 text/type
getExtension(“text/type”) 返回其type类型(js,css,jpg等类型)

path模块:require(“path”)

basepath() 将路径截取出其后面的hash值

相对路径

本地相对路径
页面是本地打开的,在这个页面中写路径:./xxx/xx xxx/xx
本地绝对路径
从根盘开始写的路径

相对网络路径
相对于当前文件的路径
绝对网络路径
协议 + 域名 + pathname

本地相对根路径
/xxx/xxx 即为 file:///c:/xxx/xxx
网络相对根路径
/xxx/xxx 即为 http://域名/xxx/xxx

模块化

模块化语法
把一系列相类似功能 封装到一个模块中,然后供使用

nodejs环境中的全局函数:require()
后端运行时,引入第三方js文件就用require也可以用import(es6语法)

三种模块
内置模块:
var fs = require(“fs”) //内置模块/核心模块 node.js安装时,自动按照好了

第三方模块:
var mime = require(“mime”) //第三方模块 下载别人的模块使用 npm i mime
下载第三方模块后 npm会在项目配置文件中的依赖项中写入下载的第三方模块名和版本

自定义模块:
module.exports = { } 这是导出的js

寻找当前项目中的node_modules文件夹中的对应引入的文件,在找package.json寻找其中的main
npm init 生成一个配置文件
npm init -y 直接生成不需要问版本,文件名等信息

package.json 记录整个项目的配置文件

main字段    =>项目入口,JS文件路径
script字段  =>cmd指令   npm run xxx
dependencies字段    当项目中要依赖其它工具,会在这个字段中做记录,方便以后node_modules重新下载

package.json文件中scripts对象中的dev 可以通过npm run dev 启动该指令,可以启动dev中写的指令启动多个文件

"scripts":{"dev":"node index.js"}    //启动指令,可以写多个,dev可以自己命名

npm i 按照项目配置文件,将文件中依赖的文件全都下载下来
npm i 模块名字 -g 将模块下载到Node全局按照路径里
npm i 模块名字 将模块下载到当前的项目路径里

MVC:一种设计思想

M:Model        数据模型层
V:View         视图层
C:Controller   逻辑控制层

nodemon index.js 启用nodemon组件,动态刷新服务器

Ajax

在不刷新页面的情况下去请求数据,然后把这个数据局部刷新到页面上(DOM)的技术
    xhr = XMLHttpRequest;
    xhr.oopen("type",'url',true);   布尔值表示是否是异步,
    xhr.send(string)    只可以传字符串参数
    let xhr = new XMLHttpRequest();
            // 兼容写法
            // new XMLHttpRequest()||new ActiveXObject("Microsoft.XMLHTTP")

            // 配置连接信息
            xhr.open("GET", "./xxx/xxx", true);

            // 发起网络请求
            xhr.send();

            // 等待
            xhr.onreadystatechange = function () {
                // 监听readyState的值是否改变
                if (xhr.readyState == 4) {
                // 4表示后端发回来了数据
                // xhr.stauts 表示返回的状态码
                // responseText    表示返回的内容
                }

跨域

浏览器对于Ajax请求有一个核心的安全策略:同源策略(是否是同一个服务器)
浏览器为了用户信息安全,网页中有一个网络请求技术:AJAX在网络请求时,请求的网址 和 当前页面的网址不是同一台服务器(非同源),浏览器就会拒绝处理服务器发送的数据

如果用Ajax去请求一个非同源的网址,就会被跨域限制,只有Ajax才会有跨域限制
可以网络请求:a标签、img标签、link标签、xxx-url、script-src、form-action、浏览器的地址栏

同源策略
浏览器的一种安全策略:指两个网址的 协议ip port(端口)三者一样就代表同源

CORS(跨域资源共享)

AJAX跨其它的服务器请求数据
    //给资源包设置一个头部信息
    res.setHeader("Access-Control-Allow-Origin","http://ip:port");

//  * 表示所有都可以访问,一般用于开发阶段
    res.setHeader("Access-Control-Allow-Origin","*");

JSONP (JSON with padding)

通过script标签进行网络请求
利用script的src属性可以访问外部资源,也不受同源策略影响,前端在请求时,需要通过querystring携带回调函数名,方便后端返回函数名字
但这样的方式需要后端为前端写一个json格式的接口(函数),方便前端使用

 //返回的res.end()返回的是字符串,前端页面收到后,v8引擎会去运行请求下来的资源,如果不是js编码就会报错

Proxy(代理)

前端发送请求一个不是自己服务器中的数据发送到自己的服务器,自己的服务器去请求其它服务器的方法

模块require(“request”) 第三方模块
是一个后端的网络请求工具,后端请求后端的工具
request(“网址”,function(arg1,arg2,arg3){
// arg3(data) 是请求后的数据,发送给前端,就直接访问到了其它地址
});

拓展:iframe跨域

回调地狱

Promise

promise这种设计在es5已经出现了,es6才正式出现在语法中
它被设计成一个全局构造函数,创建出来的对象,是一个特殊的数据容器
内部有三种状态:等待(pending) ==> (fulfilled) 产生正确的数据| (rejected)产生了错误的数据
then函数有一个返回值:一定是一个新的Promise对象
返回的新的Promise对象,是由传入函数的返回值决定的
一个任务开始后:同步任务优先级>异步宏任务>异步微任务==>再去执行排队的异步宏任务>同步任务>异步微任务==>。。。

Promise静态方法
Promise.resolve(data) 返回promise对象(fuifilled数据),让data产生resolve数据
Promise.resolve(reject)
Promise.resolve(data) = new Promise((resolve,reject) => {
resolve(data);
})
Promise.all([p1,p2,p3]) 数组中有许多个请求的Promise对象,都在请求数据,都请求成功后的返回值组成数组,作为对象的resolve,谁先失败就作为reject
Promise.race([p1,p2,p3]) 谁先改变状态就作为其Promise对象的数据

axios与fetch
axios:Promise封装的Ajax
fetch: 浏览器自带的API不需要网络即可用,fetch不是Ajax,采用Promise方式处理数据但不是Promise
react fetch(url) .then((res)=>{ return res.json; }) .then((data)=>{ console.log(data); })

async await
await(ES7)
ES6 -promise、指针函数
await必须放在函数里面
await必须是async修饰的函数
await让程序停止等程序执行后再继续执行下面的代码
await 会取出Promise中的数据,代替了then方法

约定优于配置

egg安装

npm init egg --type=simple

router路由

指不同的网址去执行不同的分支或者程序

注册路由时,不要与静态文件名冲突,不然会优先访问静态资源
路由处理顺序:静态文件>路由匹配(按照从顺序匹配)
```react
router.get('/*',controller.xxx) 表示所有网址都能匹配上
```

Controller

this.ctx  是Controller提供的功能,主要就是使用它提供的:给前端发送数据,访问插件功能

跨域

框架提供了 egg-cors 插件来实现cors跨域请求
```react
//下载
    npm i egg-cors  
//2.开启插件
// config/plugin.js文件
cors:{
enable: true,
package: 'egg-cors',
}
//3.配置插件   
// config/config.default.js文件
config.cors = {
    origin: '*',
    allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH'
}
```

CORS配置

    //1.下载
    npm i  egg-cors

    //2.开启插件
    // config/plugin.js文件
    cors:{
    enable: true,
    package: 'egg-cors',
    }
    //3.配置插件   
    //  config/config.default.js文件
        config.cors = {
        origin: '*',    //所有都跨域访问
        allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH'
  }

JSOP配置
前端:

     <input type="button" value="获取" οnclick="fn()">
     function fn() {
     let sc = document.createElement("script");
     sc.src = 'http://169.254.189.55:7001/api?cb=fm';
     window.fm = function (res){
         console.log(res);
     }
     document.body.appendChild(sc);
     }
 ```


```react
 //如果前端的参数中有cb=fn参数(jsonp接口参数),将会返回JSONP格式的数据,否则返回JSON格式的数据。

 //1.配置:
 // config/config.default.js文件
 config.jsonp = {
 callback: 'cb',     // 识别 query 中的 `cb` 参数
 limit: 100,         // 函数名最长为 100 个字符
 };

 //2.写接口
 // app/router.js
 module.exports = app => {
 const jsonp = app.jsonp();
 app.router.get('/api/posts', jsonp, app.controller.posts.list);
 };

也可以直接在jsonp方法中直接配置,功能一样:

    //如果前端的参数中有cb=fn参数(jsonp接口参数),将会返回JSONP格式的数据,否则返回JSON格式的数据。
    // app/router.js文件
    module.exports = app => {
    const jsonp = app.jsonp({
    callback: 'cb', //函数名,cb为前端发送来的字段,例:cb=fn
    limit: 100,
    });
    app.router.get('/api/posts', jsonp, controller.XXX);
};

代理
egg中的网络请求技术:

this.ctx.curl(url, option)

option常用配置:

method:‘GET/POST’

data:{name:“karen”} //会自动字符串化

返回promise对象

    //home.js文件
    async cors(){
    let data1=await this.ctx.curl("http://www.baidu.com",{method:"GET",data:{pwd:123}})
    this.ctx.body=data1
    }

GET|POST

GET

    参数会拼接到url中发送给后端 --不安全,容易被截取到
```react
     this.ctx.request.query  后端接收前端的数据
1.
    axios("协议://ip:port/pathname?参数querystring")
    .then()
2.
    //第二个参数表示给后端传送的数据,必须是对象有一个params属性用来放传的内容
    axios(url,{params:{key:value})
    .then()
    axios.get()和axios()是一样的
```
    浏览器的地址栏只能发送get请求,接受的数据会直接读取
    如果解析失败会下载
    
    a标签的href属性也[只能]发get请求,并且是点击事件触发了默认事件才会发送get请求
    
    img-src:[只能]发起get请求,返回的数据渲染成图片,如果非图片编码就会"破裂"

    link-href
    [只能]发起get请求 返回的数据按照功能使用
    from表单
    发送GET|POST等等给action属性对应的url 发送请求
    get请求会把from表单
    返回的数据同a标签

POST

暗文发送,发送的数据比get要大一些

Ajax请求方式为POST,发送的内容放在send()里面,send()里面的内容只有请求方式为POST才会发送里面的内容,需要设置一个头部信息,否则后端解包失败
后端不再是router.get(),而是router.post()接收

```react
1.
    axios.post(url,{key:value}) //POST带数据方式请求
2.
    var fdata = new FormDate();
    fdata.append(key1,"value字段1");
    fdata.append(key2,"value字段2");
    axios.post(url,fdata)       //发送给后端
    .then()
```
后端接收:
this.ctx.request.body   //前端发送过来的数据包
var f = this.ctx.request.files  //前端发送过来的文件
f[0].filepath就是用户上传的文件保存在服务器的计算的临时路径,需要移动到项目目录中

//关闭csrf的安全证书验证
config.security={
 csrf:{
   enable:false
    }
}

//设置post传送数据大小
bodyParser: {
		jsonLimit: '1mb',
		formLimit: '1mb',
	}

文件上传:egg必须设置启用file模式

```react
表单:
let f1  =  new FormDate() //前端创建一个对象用来放用户上传的图片
f1.append("key","文件")   //将用户上传的图片,放在对象中,最多9个文件
window.URL.createObjectURL(URLobj)      //把图片转为一个网址,用于图片预览
axios.post(url,fdata)       //发送给后端
.then()

```
    //egg启用file模式
    // config/config.default.js文件
    config.multipart = {
    mode: 'file',
    };

egg-jwt(Json Web Token)

安装

 	npm i egg-jwt --save
    
// config/plugin.js
    exports.jwt = {
  	enable: true,
  	package: "egg-jwt"
	};
//config/config.default.js
exports.jwt = {
  secret: "tyd" 
};

// 使用例子:
const token = app.jwt.sign({ foo: 'bar' }, app.config.jwt.secret);//创建token

//解析前端发送的token
 ctx.app.jwt.verify("前端发送的数据",'tyd')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值