nodejs模拟实现博客(一)
安装node,百度查阅,node -v查询版本
node.js和javascript区别
es
定义了语法,js和nodejs都要遵守
不能操作dom,不能监听click,不能发送ajax
js
使用es语法,外加webAPI,可以操作dom,事件绑定,ajax等
nodejs
使用es语法,外加nodejsAPI,处理htpp,处理文件等
commonjs模块化,node.js使用这个模块化
a.js
function add(a, b) { return a + b } function mul(a, b) { return a * b } module.exports = { add, mul }
b.js
const { add, mul } = require('./a') const _ = require('lodash') const sum = add(10, 20) const result = mul(100, 200) console.log(sum) console.log(result) const arr = _.concat([1, 2], 3) console.log('arr...', arr)
npm init 初始化, 运行,node b.js
CommonJS模块与ES6模块的区别
CommonJS
- 对于基本数据类型,属于复制。即会被模块缓存。同时,在另一个模块可以对该模块输出的变量重新赋值。
- 对于复杂数据类型,属于浅拷贝。由于两个模块引用的对象指向同一个内存空间,因此对该模块的值做修改时会影响另一个模块。
- 当使用require命令加载某个模块时,就会运行整个模块的代码。
- 当使用require命令加载同一个模块时,不会再执行该模块,而是取到缓存之中的值。也就是说,CommonJS模块无论加载多少次,都只会在第一次加载时运行一次,以后再加载,就返回第一次运行的结果,除非手动清除系统缓存。
- 循环加载时,属于加载时执行。即脚本代码在require的时候,就会全部执行。一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。
ES6模块
- ES6模块中的值属于【动态只读引用】。
- 对于只读来说,即不允许修改引入变量的值,import的变量是只读的,不论是基本数据类型还是复杂数据类型。当模块遇到import命令时,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。
- 对于动态来说,原始值发生变化,import加载的值也会发生变化。不论是基本数据类型还是复杂数据类型。
- 循环加载时,ES6模块是动态引用。只要两个模块之间存在某个引用,代码就能够执行。
默认导出 export default 变量或者函数或者对象 默认引入 import name from "相对或绝对路径" 导出的名字和引入的名字可以不一致 按需导出 export 需要声明 变量用const var let 函数用function 按需引入 import {变量名或函数名} form "路径" 全部引入 使用 import * as 自定义name "路径" 会将默认导出和按需导出 全部引入
server开发和前端开发区别
1.服务稳定性,server端可能遭受恶意攻击
2.日志记录, 单个客户端可以意外挂掉,但是服务端不能,pm2做进程守候
3.内存优化,server端承载很多请求,cpu和内存都是稀缺资源,使用stream写日志,使用redis存session
4.安全,server端可能遭受恶意攻击,越权操作,数据库攻击,预防xss攻击,spl注入
5.集群和服务拆分,扩展服务和机器拆分流量
6.日志记录,server端要记录日志,存储日志,分析日志。
http请求概述
浏览器输入地址,会车,显示页面,经历的过程
1.浏览器DNS域名解析,建立tcp连接,发送http请求
2.server端接收http请求,处理并返回数据
3.客户端接收返回的数据,处理数据(页面渲染)
编写简单的node服务,查看参数详情
app.js, get请求
// http是node自带的模块 const http = require('http') // querystring,node自带的模块 const querystring = require('querystring') const server = http.createServer((req, res) => { console.log('method', req.method) const method = req.method // 端口后路径 const url = req.url console.log('url', req.url) // qeurysstring.parse将字符串转换成对象 req.query = querystring.parse(url.split('?')[1]) console.log('query',req.query) // res.end发送的是字符串,需要转换成字符串 res.end( JSON.stringify(req.query) ) }) server.listen(8000) console.log('OK')
浏览器中输入地址
npm init node app.js, 打印情况
app.js psot请求
const http = require("http"); const server = http.createServer((req, res) => { if (req.method === "POST") { //请求数据格式 console.log("content-type", req.headers["content-type"]); //接收数据 let postData = ""; // 监听,流式接收客户端请求的参数,chunk二进制格式 req.on("data", (chunk) => { postData += chunk.toString(); }); req.on("end", () => { console.Log(postData); res.end("hello world"); //在这里返回,因为是异步 }); } }); server.listen(8000);
postman发送post请求,写入请求参数
浏览器无法模拟,postman模拟
node app.js, 打印情况
综合演示
app.js
const http = require('http') // querystring,node自带的模块 const querystring = require('querystring') const server = http.createServer((req, res) => { const method = req.method const url = req.url const path = url.split('?')[0] const query = querystring.parse(url.split('?')[1]) // 设置返回格式为 JSON,浏览器会解析字符串的数据 res.setHeader('Content-type', 'application/json') // 返回的数据 const resData = { method, url, path, query } // 返回 if (method === 'GET') { // 返回字符串的数据 res.end( JSON.stringify(resData) ) } if (method === 'POST') { let postData = '' req.on('data', chunk => { postData += chunk.toString() }) // 接收请求参数结束后,返回响应数据 req.on('end', () => { resData.postData = postData // 返回 res.end( JSON.stringify(resData) ) }) } }) server.listen(8000) console.log('OK')
node app.js
postman模拟