Node进阶

nodejs官网
nodejs中文文档1
nodejs中文文档2

node是一个基于v8引擎渲染js的工具

把js运行在node环境下 项目中,我们会在服务器端安装一个node,然后用js去编写后台程序node 给js提供操作I/O的能力,浏览器不允许js操作I/O
node是事件驱动的 event-based system,js是单线程的,v8是多线程的,只是分配执行js是单线程的,java是线程驱动的 thread-based system   线程系统提高并发量 多线程,服务器群组,增加线程的管理难度和成本。

在这里插入图片描述

哪些时候用到node

  • npm模块化管理
  • webpack导入导出
  • webpack的process.env.NODE_ENV 设置NODE的全局环境变量
  • commonjs模块导入导出
  • webpack-dev-server 启的服务
  • 全栈开发
  • 服务器端渲染

脚本设置 process.env.NODE_ENV = “dev”

"scripts":{"start":"set NODE_ENV = dev & node index.js"
}

服务器端渲染 VS 浏览器端渲染

  • 服务器端渲染 优点是 前端渲染耗时少,有利于SEO,所有代码内容都可以看到,有利于爬虫
  • 服务器端渲染 缺点是 前端后配合不好,后台压力大,页面需要局部更新,也需要后台重新渲染,
    返回最新的结构数据(客户端需要刷新才能看到最新的数据),性能体验不好。

完全的服务器渲染是不能做到局部刷新的
淘宝京东解决性能问题方案是:骨架屏解决方案
第一屏内容是服务器渲染的(只要服务器足够给力,能够提高页面第一次打开渲染速度)
其余屏幕内容都是前后端分离(客户端渲染)

内置的events,发布-订阅者

const EventEmitter = require('events')
const myEmitter = new EventEmitter()
myEmitter.on('A', function f1(...args) {console.log(args)})//[1,2]
myEmitter.on('A', function f2(...args) {console.log(args)})//[1,2]
console.log(myEmitter.listeners('A'))// [ [Function: f1], [Function: f2] ]
myEmitter.emit('A', 1, 2)

node异步执行 常用方法

process.nextTick > setTimeout0 > setImmediate 大说明先执行

setTimeout(() => {console.log(5)
}, n) // n > 0                      
setTimeout(() => {console.log(3)
}, 0)
setImmediate(() => {console.log(4)
})
process.nextTick(() => { // 主任务完成 立马执行nextTick ,然后再去找event queue任务 这是node内置方法console.log(2)
})
console.log(1)// n足够大时  输出  1 2 3 4 5
// n值 较小时,可能每次输出的顺序不太一样  输出 1 2 3 4 是大方向,因为n值较小,输出的5会穿插在2 ~ 3 ~ 4之间诡异的事情  n值较小 且相同  每次输出的顺序却不一样

CommonJS

想啥时候用 就啥时候用 ,类似cmd

CommonJS是服务器端模块的规范,由Node推广使用,webpack也采用这种规范编写。
CommonJS模块规范主要分为三部分:模块定义、模块标识、模块引用。

优点:模块化思想,每个文件是一个独立的模块,文件之间互相不干扰。
缺点:CommonJS 是同步加载的,在服务器端,文件都是保存在硬盘上,所以同步加载没有问题,但是对于浏览器端,需要将文件从服务器端请求过来,那么同步加载就不适用了,所以浏览器不适合CommonJs,出现另一种规范AMD

exports.foo = function () {console.log(1)}
require('./index').foo() // 1
module.exports = function() {console.log(2)}
require('./index2') //2

在这里插入图片描述
在这里插入图片描述

AMD ( asynchronous module definition)

require.js
AMD 是运行在浏览器环境的一个异步模块定义规范

适合在浏览器环境中异步加载模块。可以并行加载多个模块,但依赖前置,必须提前加载所有的依赖。

html文件加上这个

<script src="./require.js" data-main='./main.js'></script>

main.js

require.config({paths: {dataService: './dataService',math: './math'}
})
require(['dataService', 'math'], function (dataService, math) {});

dataService.js

define(['math'], function (math) {function doSomething() {let result = math.add(2, 9);console.log(result);}return {doSomething};
});

math.js

define(function () {var add = function (x, y) {return x + y;};return {add: add};
});

CMD ( common module definition)

seajs

需要用到某个模块时,再加载对应依赖require,依赖就近

<script src="./sea.js"></script>
<script>seajs.use('./main.js')</script>

main.js

define(function (require, exports, module) {require('./index').four()// '444'
})

module1.js

define(function(require,exports,module){function one(){console.log('这是module 1');}module.exports = {one}
})

index.js

define(function (require, exports, module) {let module1 = require('./module1')function four() {console.log('444');}exports.four = four 
})

ES6

导入依赖前置,类似amd

export default {}
import xxx from './xxx'

node内置模块方法

fs

require('fs').readFile('./test.txt', 'utf-8',(err,v)=>{console.log(v)})
require('fs/promises').readFile('./test.txt', 'utf-8').then(v => {console.log(v)})require('fs').readFileSync('./test.txt', 'utf-8')//默认是buffer流格式,需要加utf-8转化一下
require('fs').writeFile('./test.txt','你是谁','utf-8',(err,v)=>{console.log(v)})
require('fs').appendFile('./test.txt','你是谁','utf-8',(err,v)=>{console.log(v)})

__dirname

console.log(__dirname)// E:\html\vue-element-ui\html-s\node 当前代码文件所在文件夹绝对路径

path

const path = require('path')
console.log(path.resolve('../'))// E:\html\vue-element-ui\html-s
console.log(path.basename('/1/qwer.html','.html'))// qwer
console.log(path.join('1','/2','3')) // '1\2\3'
console.log(path.parse('/home/user/dir/file.txt')) 
/* {root:'/',dir:'/home/user/dir',base:'file.txt',ext:'.txt',name:'file'}
*/
path.resolve('/foo/bar', './baz');
// 返回: '/foo/bar/baz'path.resolve('/foo/bar', '/tmp/file/');   第二个绝对路径覆盖了第一个
// 返回: '/tmp/file'path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
// 如果当前工作目录是 /home/myself/node,
// 则返回 '/home/myself/node/wwwroot/static_files/gif/image.gif'

http

const http = require('http')
const url = require('url')
const server = http.createServer((req, res) => {console.log(Object.keys(req))console.log(Object.keys(res))const {pathname,query} = url.parse(req.url, true)res.writeHead(201, {})res.end(JSON.stringify({ s: 1, fd: 'fsadfasd' }))/* 返回的可以是 readFile读取的buffer(图片) 也可以是html文件(utf-8) */
})
server.listen(4000, (v) => {console.log('localhost:4000')
})

express

express

cnpm i express cors

post请求头种类

  1. application/x-www-form-urlencoded
  2. multipart/form-data
  3. application/json

原生 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据

表单上传文件时,必须让 表单的 enctype 等于 multipart/form-data

const express = require("express");
const app = express();
const path = require("path")
var cors = require("cors");
var bodyParser = require("body-parser");
const port = 3001;//cors解决跨域问题 方法1:
var cors = require("cors"); 
app.use(cors());//手写解决跨域问题 方法2:
app.use((req, res, next) => {  res.header("Access-Control-Allow-Origin", "http://www.baidu.com:80");res.header("Access-Control-Allow-Credentials", true);res.header("Access-Control-Allow-Headers","Content-Type,Content-Length,Authorization,Accept,X-Requested-With");res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS,HEAD");req.method === "OPTIONS" ? res.send("ok") : next(); //解决浏览器发送的预请求过程
});//访问http://localhost:3001/index.json  其实是访问http://localhost:3001/public/index.json
app.use(express.static("public"));//访问http://localhost:3001/static/bindex.json  其实是访问 http://localhost:3001/files/bindex.json
app.use("/static", express.static("files"));//比上面一个设置要更加安全  目前不清楚有啥子区别
app.use("/static", express.static(path.join(__dirname, "files")));//解析post请求方式传递的参数  传参方式不同  解析的方法也不同
app.use(bodyParser.urlencoded({ extended: true })); //application/x-www-form-urlencoded
app.use(bodyParser.json()); //application/jsonapp.get("/", (req, res) => {res.send("Hello World!");
});
app.post("/urlencode", function (req, res) {console.log(req.body); //通过了bodyParser解析后,就可以打印出来前端传递的值res.json(req.body);
});
app.listen(port, () => {console.log(`listening at http://localhost:${port}`);
});

在这里插入图片描述


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部