Two 、node An introduction to the
node It's a run js Environment . Browsers also run js Environment .
The difference between the two is :
- The browser will have window and document Call to . however node No,
- node There are many modules of api, For example, file system access
- node You can switch the running environment ( Switch versions ?)
- node no need bable transformation
- node It uses commonJS, To use require
2-2 nodejs And js The difference between
nodejs = nodejsapi + ecmascript
Handle http, Processing documents, etc .
2-3 commonjs
module.export()
require
2-4,5 debuger And inspect agreement
--inspect==9229
Four 、 Develop the interface of blog project
4-1 http summary
from url The process to the browser ?
First dns analysis , After parsing, send the request , adopt http The establishment of the agreement tcp link , And then transfer the file .
The browser takes the data and builds dom Trees , establish css Trees . Merge into render Trees , Then render , Inject js.DNS analysis , establish TCP Connect , send out http request
server Received http request , Process and return .
The client receives the returned data , Processing data ,( Such as rendering the page , perform js)
Remote address Namely dns Result of query
4-4 Handle http A comprehensive example of a request
const http = require("http");
const port = 3000
const server = http.createServer((req, res) => {
res.setHeader("Content-Type", "application/json")
const url = req.url
const method = req.method
res.end(`${url}${method}`);
})
server.listen(port, () => {
console.log(` The server is running at http://localhost:${port}/`)
})
console.log("ok")
4-5 Build development environment
- Use nodemon Detect file changes , Automatic restart node.
- corss-env Set the environment variable
npm i nodemon cross-env --save-dev
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "cross-env NODE_ENV=dev nodemon ./bin/www.js"
},
4-6 Initialize route
hostname:nodejs.cn
pathname:/api/blog/list
query:?name=zhangsan&keyword=123
const method = res.method // post get
const url = res.url // url
const path = res.url.split("?")[0] //
4-7 Develop routing
establish SuccessModel
、ErrorModel
.
class BaseModel {
constructor(data, message) {
if (typeof data === "string") {
this.message = data;
message = null;
data = null
}
if (data) {
this.data = data;
}
if (message) {
this.message = message;
}
}
}
class SuccessModel extends BaseModel {
constructor(data, message) {
super(data, message);
this.error = 0
}
}
class ErrorModel extends BaseModel {
constructor(data, message) {
super(data, message);
this.error = -1
}
}
module.exports = {
SuccessModel,
ErrorModel
}
4-8 Develop routing ( Blog details routing )
const fs = require('fs');
const path = require('path');
function getFileContent(fileName) {
const fullFileName = path.resolve(__dirname, 'file', fileName)
const promise = new Promise((resolve, reject) => {
fs.readFile(fullFileName, (err, data) => {
if (err) {
reject(err);
}
resolve(JSON.parse(data));
})
})
return promise;
}
getFileContent('a.json').then(aDate => {
console.log(aDate);
return getFileContent(aDate.next);
}).then((bData) => {
console.log(bData);
return getFileContent(bData.next);
}).then((cData) => {
console.log(cData);
});
4-9 Develop routing ( Handle POSTData)
// Used for processing post data
const getPostData = (req) => {
const promise = new Promise(() => {
if (req.method !== 'POST') {
resolve({})
return
}
if (req.headers['content-type'] !== "application/json") {
resolve({})
return
}
})
// Listening to stream data
let postData = ''
res.on('data', chunk => {
postData += chunk.toString()
})
res.on('end', () => {
if (!postData) {
resolve({})
return
}
resolve(
JSON.parse(postData)
)
})
return promise
}
Update and delete data, etc ....
5 database
MySql
use myblog;
-- Look up the table
-- show tables;
-- insert into blogs(title,content,createtime,author)values(" Ms. Hu 2 The title of the "," Ms. Hu 2 The content of ",1585645673144,"mjmjmj");
SELECT * FROM myblog.users LIMIT 0,1000;
-- select username from users;
-- select * from users where password like '%1%' order by id desc;
-- select * from blogs;
-- ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password' PASSWORD EXPIRE NEVER;
-- ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '11111111';
-- flush privileges
-- insert into blogs (title, content, createtime, author)values ('hhhhhh', 'jjhhhhh', 1585646800912, 'mjmjmj');
-- select username, realname from users where username='mjmjmj' and password='321654a.'
-- to update
-- SET SQL_SAFE_UPDATES = 0;
-- update users set state = 0;
-- update users set username ='huhuhu' where id = '2';
-- Delete
-- delete from blogs where id='1';
5.4 nodejs operation database
const mysql = require('mysql');
const con = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '11111111',
port: '3306',
database: 'myblog',
})
// Start connecting
con.connect()
// perform sql
const sql = 'select * from users;';
con.query(sql, (err, result) => {
if (err) {
console.log(err);
return;
}
console.log(result);
})
con.end();
const mysql = require('mysql');
const { MYSQL_CONF } = require("../conf/db");
// Create linked objects
const con = mysql.createConnection(MYSQL_CONF);
// Establishing a connection
con.connect();
// Unified execution sql Function of
function exec(sql) {
const promise = new Promise((resolve, reject) => {
con.query(sql, (err, result) => {
if (err) {
reject(err);
return
}
resolve(result)
})
})
return promise;
}
con.end();
module.exports = {
exec
}
6.2 Cookie Introduce
What is? cookie?
js How to operate cookie, How to view cookie?
server End operation cookie, Implement login authentication 、
characteristic :
- Maximum 5kb
- Cross domain not shared ,
- Structured data can be saved
- Send each time http request , The cookoie Send to cookie
- server The end can be modified cookie, And return it to the client
- The client can also use the js modify cookie, And return it to server End ( Limited )
- See which domain is requested , Which domain to request , Take which cookie
Inside the request header cookie
Local cache cookie
domin:cookie Domain name in effect
path: yes cookie Effective path
modify cookie
With localStorage , Local modification cookie It's not much
nodejs modify cookie
// analysis cookie
req.cookie = {}
const cookieStr = req.headers.cookie || '' // k1=v1;k2=v2;k3=v3
cookieStr.split(';').forEach(item => {
if (!item) {
return
}
const arr = item.split('=')
const key = arr[0].trim()
const val = arr[1].trim()
req.cookie[key] = val
})
nodejs setCookie
// Sign in
if (method === 'POST' && req.path === '/api/user/login') {
const { username, password } = req?.body
const result = login(username, password)
return result.then(data => {
if (data.username) {
// operation cookie
res.setHeader('SetCookie', `username=${data.username}`)
return new SuccessModel()
}
return new ErrorModel(' Login failed ')
})
}
6.4 cookie Make restrictions
Set up httpOnly
res.setHeader('SetCookie', `username=${data.username}; path=/; httpOnly`)
// obtain cookie The expiration time of
const getCookieExpires = () => {
const d = new Date()
d.setTime(d.getTime() + (24 * 60 * 60 * 1000))
console.log('d.toGMTString() is ', d.toGMTString())
return d.toGMTString()
}
res.setHeader('Set-Cookie', `userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}`)
6.6 session
cookie in Will expose username, It's dangerous userid
、sid
、conentid
, Corresponding server End username.
- session Is directly js Variable , Put it in nodejs In process memory ;
- Too much memory , It's going to blow up the process space
- Between multiple processes , Data can't be shared
6.8 redis
redis solve Multi process
Can't communicate with each other session
The problem of ( Squish , There is no data sharing between multiple processes .), Is the server side commonly used cache tool .
web server
The most commonly used cache database , Data is stored in memory , comparison mysql Fast reading and writing , But it's more expensive , Power loss .
- Separate services , And nodejs It's just a calling relationship between them . It's like mysql equally , So there's no crowding .
- Multiple processes access the same redis. therefore session It's going to sync .
- redis Scalable , Even if the number of users increases , That can also add machines , It can be expanded into clusters .
session High performance requirements
, Because every time you send a request . It doesn't matter if you lose the power , Log in again . So it can't exist directly mysql in .
6.9
const redis = require('redis');
const { REDIS_CONF } = require('../conf/db');
// Create client
const redisClient = redis.createClient(REDIS_CONF);
redisClient.on('error', (error) => {
console.log(error);
})
function set(key, val) {
if (typeof val === "object") {
val = JSON.stringify(val);
}
redisClient.set(key, val, redis.print);
}
function get(key) {
const promise = new Promise((resolve, reject) => {
redisClient.get(key, (err, val) => {
if (err) {
reject(err)
return
}
if (val == null) {
resolve(null);
return
}
try {
resolve(JSON.parse(val))
} catch (ex) {
resolve(val)
}
resolve(val);
})
});
return promise;
}
module.exports = {
set,
get
}
set myname mj
get myname // mj
get * // Get all key value
// obtain session
req.sessionId = userId
get(req.sessionId).then(sessionData => {
if (sessionData == null) {
// initialization redis Medium session value
set(req.sessionId, {})
// Set up session
req.session = {}
} else {
// Set up session
req.session = sessionData
}
// console.log('req.session ', req.session)
// Handle post data
return getPostData(req)
})
.then(postData => {
......
}
6.14 Why use nginx
Because of a service from the front end and nodejs The service from is not the same port , and cookie Cross domain not shared .
Use http-server Start a front-end service . Port set to 8001.
nodejs:8000 port
Everybody go to 8080 port .
6.15 High performance web The server nginx), Open source , free
If requested /
root directory , request html, that ,nginx Go back straight back to html
If requested /api/blog/...
Come first nginx port 8000, And then to node Port of service ,8001.
Agents that are not visible to clients , be called Reverse proxy
Use easyconnect Connect , go by the name of Forward agency
, The client can control
- Test if the configuration file format is correct :
ngnix -t
- start-up nginx restart nginx -s reload
- stop it ngnix -s stop
sudo vi /usr/local/etc/nginx/nginx.conf
The main thing is to add the code , Then comment out some of the above .
location / {
proxy_pass <http://localhost:8001>;
}
location /api/{
proxy_pass <http://localhost:8000>;
proxy_set_header Host $host;
}
It's been a long time , Is to understand what is redis, What is? session, What is? ngnix, In the code is a match .