因为切换输入法实在麻烦,能用英文写的都用英文写了。。。
Node.js
1. Modules Introduce
http module
// export 'http' module
var http = require('http');
/*
* request: get the message that url transmit
* response: give browser the response message
*
* */
http.createServer(function (req, res){
// response head setting
res.writeHead(200,{'Content-Type': 'text/plain'});
// print a sentence in the page and end the response
res.end('The end of the fxxking world');
}).listen(8081);
console.log('Server ruuning at http://127.0.0.1:8081/');
const http = require('http');
/*
* req get the message that url transmit
* res give browser the response message
*
* */
http.createServer(function(req, res){
console.log(req.url); // get url
// set response head
// status 200, file type: html, charset: utf-8
res.writeHead(200,{"Content-Type":"text/html;charset='utf-8'"});
res.write('<head><meta charset="UTF-8"></head>')
res.write('你吃了吗');
res.write('<h2>你吃了吗</h2>')
res.end(); // end response
}).listen(8081);
console.log('Server ruuning at http://127.0.0.1:8081/');
url module
const url = require('url')
var api = 'http://www.itying.com?name=zhangsan&age=20';
// console.log(url.parse(api,true));
var getValue = url.parse(api,true).query;
console.log(getValue);
console.log('name: ${getValue.name}--age:${getValue.age}');
http and url module
const http = require('http');
const url = require('url')
/*
* req :get the message that url transmit
* res :give browser the response message
*
* */
http.createServer(function(req, res){
console.log(req.url); // get url
// set response head
// status 200, file type: html, charset: utf-8
res.writeHead(200,{"Content-Type":"text/html;charset='utf-8'"});
res.write('<head><meta charset="UTF-8"></head>')
console.log(req.url);
if (req.url!='/favicon.ico'){
var userInfo = url.parse(req.url,true).query;
console.log(`name: ${userInfo.name}--age:${userInfo.age}`);
}
res.end('你吃了吗'); // end response
}).listen(8081);
console.log('Server ruuning at http://127.0.0.1:8081/');
custom modules
use exports
without export modules:
const http = require('http');
function formatApi(api){
return "http://www.itying.com/" + api;
}
http.createServer(function(req, res){
res.writeHead(200,{"Content-Type":"text/html;charset='utf-8'"});
res.write('<head><meta charset="UTF-8"></head>')
res.write('你吃了吗');
var api = formatApi('api/plist');
res.write(api);
res.end(); // end response
}).listen(8081);
console.log('Server ruuning at http://127.0.0.1:8081/');
pack into one module:
function formatApi(api){
return "http://www.itying.com/" + api;
}
exports.formatApi = formatApi
const http = require('http');
const tool = require('./module/tool.js');
http.createServer(function(req, res){
res.writeHead(200,{"Content-Type":"text/html;charset='utf-8'"});
res.write('<head><meta charset="UTF-8"></head>')
res.write('你吃了吗');
var api = tool.formatApi('api/focus');
res.write(api);
res.end(); // end response
}).listen(8081);
console.log('Server ruuning at http://127.0.0.1:8081/');
const tool = require(’./module/tool.js’); 注意路径
可以写成
const tool = require(’./module/tool’); 把点js后缀去掉
request.js
var obj={
get: function(){
console.log('get data from server')
},
post:function(){
console.log('commit data')
}
}
exports.xxxx=obj
const request = require('./module/request')
console.log(request)
C:\Users\Jinondo\WebstormProjects\nodejs1215>node commonjs03.js
{ xxxx: { get: [Function: get], post: [Function: post] } }
use module.exports
var obj={
get: function(){
console.log('get data from server')
},
post:function(){
console.log('commit data')
}
}
module.exports = obj
const request = require('./module/request')
console.log(request)
print information:
C:\Users\Jinondo\WebstormProjects\nodejs1215>node commonjs03.js
{ get: [Function: get], post: [Function: post] }
another ways to export
var obj={
get: function(){
console.log('get data from server')
},
post:function(){
console.log('commit data')
}
}
// exports.xxxx=obj
// module.exports = obj
exports.get = function(){
console.log('get data from server')
}
exports.post = function(){
console.log('commit data')
}
const request = require('./module/request')
console.log(request)
request.get()
default modules directory
index.js
exports.get = function(){
console.log('get data from server')
}
exports.post = function(){
console.log('commit data')
}
commonjs.js
const axios = require('myAxios')
console.log(axios)
axios.get()
axios.post()
the directory construture
User this kind of directory, notice the ‘node_modules’ and ‘index.js’
and there are three methods to get the modules
const axios = require('./node_modules/myAxios/index.js')
or
const axios = require('myAxios/index.js')
or
const axios = require('myAxios')
it must be the name of 'index.js’
if there is a constructure like this:
you will find the const db = require('db')
it can’t work
because nodejs will only search for the index.js
so you can cd into the db directory and type code:
npm init --yes
to init and create a package.json:
{
"name": "db",
"version": "1.0.0",
"description": "",
"main": "db.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
and then it will work.
2. npm modules
third party modules
-
create a empty directory and type
npm init
, create the package.json -
Use
npm intstall xxx --save
to install modules to your project
make sure add the
--save
to add the dependencies to the package.jsonand when share the project to others, you dont need to copy the node_modules directory
you can just user
npm i
and then it will help you init the dependencies and modules that you propject need.
md5 and silly-datetime
const md5 = require('md5')
console.log(md5('123456'))
var sd = require('silly-datetime');
var date = sd.format(new Date(), 'YYYY-MM-DD HH:mm');
console.log(date)
Specify a module’s version
use npm install xxx@1.1.1 --save
3. fs module
fs.stat
var fs = require('fs')
// determine a file or a directory
fs.stat('./package.json',(err, stat)=>{
if (err){
console.log(err);
return;
}
console.log(`is it a file? ${stat.isFile()}`);
console.log(`is it a directory? ${stat.isDirectory()}`)
})
fs.mkdir
var fs = require('fs')
// create a directory
fs.mkdir('./css',(err)=>{
if (err){
console.log(err)
return;
}
console.log('Successfully created')
})
fs.writeFile
var fs = require('fs')
// create a file and write into something
// if the file has existed, it will substitute the origin file!
fs.writeFile('./html/index.html','hello nodejs, you are so fucking pretty??',(err)=>{
if(err){
console.log(err);
return;
}
console.log('Successfully');
})
fs.appendFile
var fs = require('fs')
// create a file and write into something
// if the file has existed, it will append the content after
fs.appendFile('./css/base.css','body{color:red}',(error)=>{
if (error){
console.log(error);
return;
}
console.log('append file successfully')
})
fs.readFile
var fs = require('fs')
// read file
fs.readFile('./html/index.html',(err,data)=>{
if (err){
console.log(err);
return;
}
console.log(data)
// concert Buffer to String
console.log(data.toString())
})
fs.readdir
var fs = require('fs')
// read directory structure
fs.readdir('./html/',(err, files)=>{
if (err){
console.log('err');
return;
}
console.log(files);
})
fs.rename
var fs = require('fs')
// rename a file or move a file
fs.rename('./css/aaa.css','./css/index.css',(error)=>{
if (error){
console.log(error);
return;
}
console.log('rename successfully');
})
var fs = require('fs')
// rename a file or move a file
fs.rename('./css/index.css','./html/index.css',(error)=>{
if (error){
console.log(error);
return;
}
console.log('move successfully');
})
fs.rmdir
var fs = require('fs')
// delete a directory
fs.rmdir('./aaaaa',(err)=>{
if (err){
console.log(err);
return;
}
console.log('delete directory successfully')
})
fs.unlink
var fs = require('fs')
//delete a file
fs.unlink('./aaaaa/index.css',(err)=>{
if (err){
console.log(err);
return;
}
console.log('delete a file successfully')
})
if there is any file in the directory you want to delete, rmdir will fail
must delete files in the directory and then you can delete the directory
4. Examples for fs module
write a mkdir
Determine if there is a specific file, if not, create it
// determine if there is a specific file, if not, create it
const fs = require('fs');
var path = './upload';
fs.stat(path,(err, stats)=>{
if (err){
// create directory
mkdir(path);
return;
}
if (stats.isDirectory()){
console.log('upload directory existed')
}else{
fs.unlink(path,(err)=>{
if(!err){
mkdir(path);
}else{
console.log('something error with the data transmitted')
}
})
}
})
function mkdir(dir){
fs.mkdir(dir,(err)=>{
if (err){
console.log(err);
return;
}
})
}
third party module: mkdirp
const mkdirp = require('mkdirp')
// return value is a Promise resolving to the first directory created
mkdirp('./upload').then(made =>
console.log(`made directories, starting with ${made}`))
or
const mkdirp = require('mkdirp')
// return value is a Promise resolving to the first directory created
mkdirp('./upload/aaa/xxx').then(made =>
console.log(`made directories, starting with ${made}`))
display the content of a directory
first show the wrong way to solve this problem ----- use 'for loop’
const fs = require('fs')
var path = './wwwroot';
var dirArr = [];
fs.readdir(path,(err, files)=>{
if (err){
console.log(err);
return;
}
for (var i=0;i<files.length;i++){
fs.stat(path+'/'+files[i],(err, stats)=>{
if (stats.isDirectory()){
dirArr.push(files[i]);
}
})
}
console.log(dirArr);
})
console.log(dirArr);
codes above can’t work, you will get
[]
[]
another wrong example
// it will print three '3'
for(var i = 0;i<3;i++){
setTimeout(function (){
console.log(i);
},100)
}
3
3
3
the correct way to sovle this problem ( or you can user async and await):
const fs = require('fs')
var path = './wwwroot';
var dirArr = [];
fs.readdir(path,(err, files)=>{
if (err){
console.log(err);
return;
}
(function getDir(i){
if (i==files.length){
console.log(dirArr);
return;
}
fs.stat(path+'/'+files[i],(err, stats)=>{
if (stats.isDirectory()){
dirArr.push(files[i]);
}
getDir(i+1);
})
})(0)
})
5. asynchronization
Promise
because of the asynchronization, the code as follow won’t work.
function getData(){
setTimeout(function (){
var name="Zhang San"
return name;
},1000);
}
console.log(getData());
D:\JetBrains\WebStormProjects\nodejsLearning\nodejs12162>node app.js
undefined
use callback function:
function getData(callback){
setTimeout(function (){
var name="Zhang San"
callback(name)
},1000);
}
// get data from asynchronous method externally
getData(function (name){
console.log(name);
})
user Prominse
var p = new Promise(function(resolve, reject){
setTimeout(function (){
var name="Zhang San";
resolve(name);
},1000);
})
p.then(function (data){
console.log(data);
})
or pack into a funtion
function getData(resolve, reject){
setTimeout(function (){
var name="Zhang San HAHA";
resolve(name);
},1000);
}
var p = new Promise(getData)
p.then(function (data){
console.log(data);
})
async & await
async function test(){
return "hello fxxk you";
}
console.log(test());
get data from async function by using await:
async function test(){
return "hello fxxk you";
}
async function main(){
var data = await test();
console.log(data);
}
main();
or
async function test(){
return new Promise((resolve, reject)=>{
setTimeout(function (){
var name="Zhang San HAHA";
resolve(name);
},1000);
})
}
async function main(){
var data = await test();
console.log(data);
}
main();
Example
display the content of a directory
const fs = require('fs')
async function isDir(path){
return new Promise((resolve, reject)=>{
fs.stat(path,(err, stats)=>{
if (err){
console.log(err);
reject(err);
return;
}
if (stats.isDirectory()){
resolve(true);
}else{
resolve(false)
}
})
})
}
function main(){
var path = './wwwroot';
var dirArr = [];
fs.readdir(path,async (err, files)=> {
if (err) {
console.log(err);
return;
}
for (var i=0;i<files.length;i++){
if (await isDir(path+'/'+files[i])){
dirArr.push(files[i]);
}
}
console.log(dirArr);
})
}
main();
6. Stream Operation
use for a large number of data
fs.createReadStream
const fs = require('fs')
var readStream = fs.createReadStream('./data/input.txt');
var count = 0;
var str = '';
readStream.on('data',(data)=>{
str += data;
count++;
})
readStream.on('end',()=>{
console.log(str);
console.log(count);
})
readStream.on('error',(err)=>{
console.log(err);
})
the end of the fxxking world
the end of the fxxking world
the end of the fxxking world
the end of the fxxking world
the end of the fxxking world
the end of the fxxking world
1
fs.createWriteStream
const fs = require('fs')
var str = '';
for (var i = 0; i < 500; i++) {
str += 'the end of the fxxking world, i like it\n';
}
var writeStream = fs.createWriteStream('./data/output.txt');
writeStream.write(str);
// signal the end of the file
// you must add this line of code
writeStream.end();
writeStream.on('finish',()=>{
console.log('finish writing');
})
pipe operation
const fs = require('fs')
var readStream = fs.createReadStream('./aaa.png')
var writeStream = fs.createWriteStream('./data/aaa.png');
readStream.pipe(writeStream);
you can rename the file as well
7. Create a static web server [1]
app.js
const http = require('http');
const fs = require('fs');
const common = require('./modules/common')
const path = require('path')
// import the url modules to get url with parameters
const url = require('url')
http.createServer(function (req,res){
// http://127.0.0.1:3000/test.html
// http://127.0.0.1:3000/index.html
// get url with parameters
let pathname = url.parse(req.url).pathname;
pathname = pathname=='/'?'/index.html':pathname;
// get the suffix
let extname = path.extname(pathname);
if (pathname!='/favicon.ico'){
fs.readFile('./static/'+pathname,(err, data)=>{
if (err){
res.writeHead(200,{'Content-Type':'text/html;charset="utf-8"'});
res.end('404 NOT FOUND');
}
let mime = common.getMime(extname);
// for getting the correct Content-Type
res.writeHead(200,{'Content-Type':`${mime};charset="utf-8"`});
res.end(data);
})
}
}).listen(3000);
console.log('Server running at http://127.0.0.1:3000/');
common.js
// for getting the correct Content-Type
exports.getMime = function(extname){
switch (extname){
case '.html':
return 'text/html';
case '.css':
return 'text/css';
case '.js':
return 'text/javascript';
default:
return 'text/html';
}
}
8. Create a static web server [2]
on the basic of code above, we apend a module function to analyze more file type, such as json, jpg…
app.js
const http = require('http');
const fs = require('fs');
const common = require('./modules/common')
const path = require('path')
// import the url modules to get url with parameters
const url = require('url')
http.createServer(function (req,res){
// http://127.0.0.1:3000/test.html
// http://127.0.0.1:3000/index.html
// get url with parameters
let pathname = url.parse(req.url).pathname;
pathname = pathname=='/'?'/index.html':pathname;
// get the suffix
let extname = path.extname(pathname);
if (pathname!='/favicon.ico'){
fs.readFile('./static/'+pathname,async (err, data)=>{
if (err){
res.writeHead(200,{'Content-Type':'text/html;charset="utf-8"'});
res.end('404 NOT FOUND');
}
let mime = await common.getFileMime(extname);
res.writeHead(200,{'Content-Type':`${mime};charset="utf-8"`});
res.end(data);
})
}
}).listen(3000);
console.log('Server running at http://127.0.0.1:3000/');
common.js
const fs = require('fs')
exports.getMime = function(extname){
switch (extname){
case '.html':
return 'text/html';
case '.css':
return 'text/css';
case '.js':
return 'text/javascript';
default:
return 'text/html';
}
}
// the new function
exports.getFileMime = function (extname){
return new Promise((resolve, reject)=>{
fs.readFile('./data/mime.json',(err, data)=>{
if (err){
console.log(err);
reject(err);
return;
}
let mimeObj = JSON.parse(data.toString());
// console.log(mimeObj[extname]);
resolve(mimeObj[extname])
})
})
}
In the getFileMime function, we use asynchronous method (return a Promise) to return data.
So in the app.js, we should use async and await to parse the asynchronous operation to synchronous
There is another way to return data in getFileMime without asyncchronization
Use fs.readFileSync:
exports.getFileMime = function (extname){
var data = fs.readFileSync('./data/mime.json');
let mimeObj = JSON.parse(data.toString());
return mimeObj[extname];
}
the part changed in app.js:
if (pathname!='/favicon.ico'){
fs.readFile('./static/'+pathname,(err, data)=>{
if (err){
res.writeHead(200,{'Content-Type':'text/html;charset="utf-8"'});
res.end('404 NOT FOUND');
}
let mime = common.getFileMime(extname);
res.writeHead(200,{'Content-Type':`${mime};charset="utf-8"`});
res.end(data);
})
}
just delete the async and await
9. Create a static web server [3]
pack the operation of creating stacic web server into a module
app.js
const http = require('http');
const routes = require('./modules/routes');
http.createServer(function (req,res){
routes.static(req,res,'static');
}).listen(3000);
console.log('Server running at http://127.0.0.1:3000/');
routes.js
const fs = require('fs')
const path = require('path')
const url = require('url')
function getFileMime(extname){
var data = fs.readFileSync('./data/mime.json');
let mimeObj = JSON.parse(data.toString());
return mimeObj[extname];
}
exports.static = function(req, res,staticPath){
// get url with parameters
let pathname = url.parse(req.url).pathname;
pathname = pathname=='/'?'/index.html':pathname;
// get the suffix
let extname = path.extname(pathname);
if (pathname!='/favicon.ico'){
fs.readFile('./'+ staticPath + pathname,(err, data)=>{
if (err){
res.writeHead(200,{'Content-Type':'text/html;charset="utf-8"'});
res.end('404 not found');
}
let mime = getFileMime(extname);
res.writeHead(200,{'Content-Type':`${mime};charset="utf-8"`});
res.end(data);
})
}
}
10. Route
make a route manually
on the basic of the 9 part: Create a static web server [3], we create a route by ourselves
app.js
const http = require('http');
const routes = require('./modules/routes');
const url = require('url')
http.createServer(function (req,res){
routes.static(req,res,'static');
// get url
let pathname = url.parse(req.url).pathname;
if (pathname=='/login'){
res.writeHead(200,{'Content-Type' : 'text/html;charset="utf-8"'});
res.end('login');
} else if (pathname=='/register'){
res.writeHead(200,{'Content-Type' : 'text/html;charset="utf-8"'});
res.end('register');
}else if (pathname=='/admin'){
res.writeHead(200,{'Content-Type' : 'text/html;charset="utf-8"'});
res.end('admin');
}else {
res.writeHead(200,{'Content-Type' : 'text/html;charset="utf-8"'});
res.end('404 NOT FOUND');
}
}).listen(3000);
console.log('Server running at http://127.0.0.1:3000/');
routes.js
const fs = require('fs')
const path = require('path')
const url = require('url')
function getFileMime(extname){
var data = fs.readFileSync('./data/mime.json');
let mimeObj = JSON.parse(data.toString());
return mimeObj[extname];
}
exports.static = function(req, res,staticPath){
// get url with parameters
let pathname = url.parse(req.url).pathname;
pathname = pathname=='/'?'/index.html':pathname;
// get the suffix
let extname = path.extname(pathname);
if (pathname!='/favicon.ico'){
try {
let data = fs.readFileSync('./'+ staticPath + pathname);
if (data){
let mime = getFileMime(extname);
res.writeHead(200,{'Content-Type':`${mime};charset="utf-8"`});
res.end(data);
}
}catch (error){
console.log('Not found');
// console.log(error);
}
}
}
The significant points:
- In the app.js, you should get the url and then you’re able to do some business logic.
- However after you do the thing in the first step, you will find that the static resources can not be found by the url like http://127.0.0.1/index.html. because the function to create a static web server is a asynchronous function, the code after it will faster end the http server.
- So you should reform the asynchronous function to a synchronous one by using readFileSync().
11. EJS & Post & Get
EJS
on the basic of part 10 Route, change some codes to do a example of EJS
app.js
const http = require('http');
const routes = require('./modules/routes');
const url = require('url')
const ejs = require('ejs')
http.createServer(function (req,res){
routes.static(req,res,'static');
// get url
let pathname = url.parse(req.url).pathname;
if (pathname=='/login'){
let msg = "data in database";
let list = [
{
brand : 'nike'
},
{
brand : 'visvim'
},
{
brand : 'carhartt'
},
{
brand : 'adidas'
},
{
brand : 'nigel cabourn'
},
];
// ================ the significant part =============
ejs.renderFile('./views/login.ejs',{
msg: msg,
list:list
},(err, data)=>{
res.writeHead(200,{'Content-Type' : 'text/html;charset="utf-8"'});
res.end(data);
})
// ================ the significant part =============
} else if (pathname=='/register'){
res.writeHead(200,{'Content-Type' : 'text/html;charset="utf-8"'});
res.end('register');
}else if (pathname=='/admin'){
res.writeHead(200,{'Content-Type' : 'text/html;charset="utf-8"'});
res.end('admin');
}else {
res.writeHead(200,{'Content-Type' : 'text/html;charset="utf-8"'});
res.end('404 NOT FOUND');
}
}).listen(3000);
console.log('Server running at http://127.0.0.1:3000/');
views/login.ejs
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Login</title>
</head>
<body>
<h2>ejs template engine</h2>
<h3>This is a login page</h3>
<%=msg%>
<br>
<ul>
<%for(var i=0;i<list.length;i++){%>
<li>
<%=list[i].brand%>
</li>
<%}%>
</ul>
</body>
</html>
doc: https://www.npmjs.com/package/ejs
Get method
C:\Users\Jinondo>node
Welcome to Node.js v12.18.2.
Type ".help" for more information.
> url.parse('http:/127.0.0.1/index?a=1&b=2',true);
Url {
protocol: 'http:',
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?a=1&b=2',
query: [Object: null prototype] { a: '1', b: '2' },
pathname: '/127.0.0.1/index',
path: '/127.0.0.1/index?a=1&b=2',
href: 'http:/127.0.0.1/index?a=1&b=2'
}
>
> url.parse('http:/127.0.0.1/index?a=1&b=2',true).query
[Object: null prototype] { a: '1', b: '2' }
Post method
the part changed in app.js above:
if (pathname=='/login'){
ejs.renderFile('./views/form.html',{},(err, data)=>{
res.writeHead(200,{'Content-Type' : 'text/html;charset="utf-8"'});
res.end(data);
})
} else if (pathname=='/doLogin'){
// get 'post' data
let postData = '';
// get chunk
req.on('data',(chunk)=>{
postData += chunk;
})
req.on('end',()=>{
console.log(postData);
res.end(postData);
})
}