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/json

app.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}`);
});

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值