运行命令:node server.js
一、创建服务器
server.js:
const http = require('http');
const fs = require('fs');
const server = http.createServer((req, res) => {
// 读取 www 文件夹中的 index.html 文件
// req.url 是 /index.html
var file_url = './www' + req.url;
fs.readFile(file_url, (err, data) => {
err ? res.write("404") : res.write(data);
res.end();
});
});
server.listen(8080);
// 访问 localhost:8080/index.html,显示内容
二、get 数据解析
HTML 页面中通过 get 请求提交表单,需要转为 json 对象。
index.html:
<body>
<form action="http://localhost:8080/aaa" method="get">
用户名:<input type="text" name="user" value=""><br>
密码:<input type="password" name="pass" value=""><br>
<input type="submit" value="提交"><br>
</form>
</body>
方法一:引入 querystring 模块将 url 转为 json 对象
querystring 适用于解析user=xl&pass=123
这种形式。
server.js:
const http = require('http');
const querystring = require('querystring');
const server = http.createServer((req, res) => {
console.log(req.url); // 不用 querystring 之前:'/aaa?user=xl&pass=123'
var json = {};
if (req.url.indexOf('?') != -1) {
var arr = req.url.split('?');
var url = arr[0];
json = querystring.parse(arr[1]);
} else {
var url = req.url;
}
res.end();
})
server.listen(8080);
方法二:引入 url 模块将 url 转为 json 对象
url 适用于解析/aaa?user=xl&pass=123
这种形式。
server.js:
const http = require('http');
const urlLib = require('url');
http.createServer((req, res) => {
var obj = urlLib.parse(req.url, true);
var url = obj.pathname; // '/aaa'
var json = obj.query; // {user:xl,pass:123}
res.end();
}).listen(8080);
三、post 数据解析
const http = require('http');
const querystring = require('querystring');
http.createServer((req, res) => {
// post 请求将 data 数据切分为多段传输
var str = ''; // 接收数据
var i = 0;
req.on('data', data => {
console.log(`第${i++}次收到数据`);
str+=data;
})
// end 数据全部到达
req.on('end', () => {
var json = querystring.parse(str);
console.log(json);
})
}).listen(8080);
四、服务器整合
const http = require('http');
const fs = require('fs');
const urlLib = require('url');
const querystring = require('querystring');
const server = http.createServer((req, res) => {
// GET
var obj = urlLib.parse(req.url, true);
var url = obj.pathname;
const GET = obj.query;
// POST
var str = '';
req.on('data', data => {
str+=data;
});
req.on('end', () => {
const POST = querystring.parse(str);
// 文件请求
var file_url = './www'+url;
fs.readFile(file_url, (err, data) => {
err ? res.write('404') : res.write(data)
res.end();
});
});
});
server.listen(8080);
五、实现注册、登录
- 定义接口
注册:/user?type=register&username=xxx&password=123456
登录:/user?type=login&username=xxx&password=123456
返回:{"status":false,"msg":"请求失败"}
- server.js
const http = require('http');
const fs = require('fs');
const urlLib = require('url');
const querystring = require('querystring');
// 构造数据
var users={}; // {"ray":"123456","zack":"123456"}
const server = http.createServer((req, res) => {
// 解析数据
var str='';
req.on('data', data => {
str+=data;
});
req.on('end', () => {
var obj = urlLib.parse(req.url, true);
const url = obj.pathname;
const GET = obj.query;
const POST = querystring.parse(str);
// 区分——接口、文件
if (url == '/user') {
switch (GET.type) {
case 'register':
if (users[GET.username]) {
res.write('{"status":false,"msg":"用户已存在"}');
} else {
users[GET.username] = GET.password;
res.write('{"status":true,"msg":"注册成功"}');
}
break;
case 'login':
if (users[GET.username] == null) {
res.write('{"status":false,"msg":"用户不存在"}');
} else if (users[GET.username] != GET.password) {
res.write('{"status":false,"msg":"用户名或密码有误"}');
} else {
res.write('{"status":true,"msg":"登录成功"}');
}
break;
default:
res.write('{"status":false,"msg":"未知的type"}');
}
res.end();
} else {
// 读取文件
var file_url = './www'+url;
fs.readFile(file_url, (err, data) => {
err ? res.write('404') : res.write(data)
res.end();
});
}
});
});
server.listen(8080);
六、模块化
//modle.js - 定义模块
exports.a = 12;
// 批量输出
module.exports = { a: 12, b: 5, c: 8 };
//index.js - 使用模块
const modle = require('./modle.js');
alert(modle.a, modle.b);
七、NPM
NPM 就是 NodeJS 的包管理工具。npm 主要用来下载,安装,管理第三方模块。
1. 发布自己创建的 npm 包
$ npm login
$ npm whoami
$ npm init [-y] // 会生成 package.json
# 自己建立 index.js 文件,例:
exports.sum = function () {
var res = 0;
for (var i = 0; i < arguments.length; i++) {
res+=arguments[i];
}
return res;
}
# 发布
$ npm publish
# 更新
$ npm update <package-name>
# 删除
$ npm unpublish --force
2. 其它 NPM 命令
npm info <package-name>
:查看包的信息npm info <package-name> versions
:查看包的版本信息npm install <package-name>
:安装指定的包npm install <package-name> -g
:全局安装包npm install <package-name>@<version>
:安装指定版本的包npm install <package-name> --save
:安装包并记录依赖,会在 package.json 中 dependencies 属性记录依赖npm uninstall <package-name>
:卸载包npm root -g
:查看全局目录npm config list
:查看 npm 配置
八、Express 框架
1、Express 是对 NodeJS 的封装,用于快速创建服务器。
const express = require('express');
const expressStatic = require('express-static');
const server = express();
server.listen(8080);
server.use(expressStatic('./www')); // 读取 www 文件夹中的静态文件
2、实现登录,接口:/login:username=xxx&password=123
const express = require('express');
const expressStatic = require('express-static');
const server = express();
server.listen(8080);
// 用户数据
var users = { 'ray': '123456', 'zack': '654321' };
server.get('/login', (req, res) => {
console.log(req.query); // GET 请求数据
var username = req.query['username'];
var password = req.query['password'];
if (users[username] == null) {
res.send({status: false, msg: '此用户不存在'});
} else if (users[username] != password) {
res.send({status: false, msg: '密码错误'});
} else {
res.send({status: true, msg: '登录成功'});
}
});
server.use(expressStatic('./www')); // 读取 www 文件夹中的静态文件
3、body-parser
处理 post 请求
const express = require('express');
const bodyParser = require('body-parser');
const server = express();
server.listen(8080);
server.use(bodyParser.urlencoded({
extended: true; // 开启扩展模式
limit: 2*1024*1024 // 数据大小限制为 2M
}));
server.use('/', (req, res) => {
console.log(req.body); // POST 请求数据
})
4、链式操作
const express = require('express');
const server = express();
server.listen(8080);
server.use((req, res, next) => {
req.a = 12;
next();
});
server.use('/', (req, res) => {
console.log(req.a); // 12
})
九、cookie 和 session 操作
npm install express express-static cookie-parser cookie-session
1、设置 cookie
const express = require('express');
const server = express();
server.listen(8080);
server.use('/aaa/a.html', (req, res) => {
res.cookie('user', 'ray', { path: '/aaa', maxAge: 24*3600*1000 }); // 设置 cookie
})
2、读取 cookie
const express = require('express');
const cookieParser = require('cookie-parser');
const server = express();
server.listen(8080);
server.use(cookieParser());
server.use('/aaa/a.html', (req, res) => {
console.log(req.cookies);
res.send('ok');
})
3、防止 cookie 被修改
const express = require('express');
const cookieParser = require('cookie-parser');
const server = express();
server.listen(8080);
server.use(cookieParser('asdfieigqn')); // 解析
server.use('/', (req, res) => {
req.secret = 'asdfieigqn';
res.cookie('user', 'ray', { signed: true });
console.log('签名cookie:', req.signedCookies); // {user: 'ray'}
console.log('无签名cookie:', req.cookies); // {}
res.send('ok');
})
4、删除 cookie
res.clearCookie('user');
5、使用 cookie-session 记录页面访问次数
const express = require('express');
const cookieParser = require('cookie-parser');
const cookieSession = require('cookie-session');
const server = express();
server.listen(8080);
server.use(cookieParser());
server.use(cookieSession({
name: 'sess',
keys: ['key1', 'key2', 'key3'],
maxAge: 24*3600*1000
}));
server.use('/', (req, res) => {
// console.log(req.session);
if (req.session['count'] == null) {
req.session['count'] = 1;
} else {
req.session['count']++;
}
console.log(req.session['count']);
res.send('ok');
})
十、模板引擎
jade
:破坏式、侵入式、强依赖。npm install jade
ejs
:温和、非侵入式、弱依赖。npm install ejs
1、使用jade
编写 HTML 结构标签
// 1.js
const jade = require('jade');
var str = jade.render('html');
console.log(str); // 输出<html></html>
// index.js
const jade = require('jade');
// 从文件中读取
var str = jade.renderFile('index.jade', { pretty: true });
console.log(str);
// index.jade 1.缩进表示层级
html
head
style
script(src="a.js")
link(href="a.css",ref="stylesheet") // 2.给标签加属性,多个属性用,分隔
body
div
ul
li 列表一
li 列表二 // 3.双标签里加内容,空格,直接写,编译生成 <li>列表二</li>
|abc // 4. | 防止被解析成 HTML 标签,效果 <body>abc</body>
// 5. 标签后加 . 使下层代码原样输出,不被解析
script.
window.onload = function(){}
- 使用
include
引入 JS 代码
// index.jade html head style script include a.js body
// a.js
window.onload = function () {
var btn = document.getElementById('btn1');
btn.onclick = function () {
alert('click me!');
};
};
- 使用变量
// index.js const jade = require('jade'); console.log(jade.renderFile('index.jade', {pretty: true, name: 'ray', json: { width: '200px', height: '200px', background: 'red' }, arr: ['aaa', 'left-wrap', 'active'] }));
// index.jade
html
head
body
-var a=12; // - 表示这是一句代码
-var b=5;
div 结果是:#{a+b}
div 用户名:#{name}
span=name // 这句效果和上句一样
div(style=json)
div(class=arr)
div(class=arr class="box")
- 输出 HTML 标签
// index.js const jade = require('jade'); console.log(jade.renderFile('index.jade', { pretty: true, content: "<h2>你好</h2>" }));
// index.jade
html
head
body
div!=content // 加 ! ,输出 <div><h2>你好</h2></div>
2、jade完整示例
// main.js
const jade = require('jade');
const fs = require('fs');
var str = jade.renderFile('index.jade', { pretty: true });
fs.writeFile('./build/index.html', str, (err) => {
if (err) console.log('编译失败');
else console.log('成功');
})
doctype
html
head
meta(charset="utf-8")
title jade测试页面
style.
div
{width:100px;height:100px;background:#ccc}
div.last {clear:left}
body
-var a=0;
while a<12
if a%4== && a!=0
div.last #{a++}
else
div=a++
生成的 HTML 页面结构:
3、ejs
的使用
// 1.HTML 中引入变量
<div><%= name %></div>
// 1.js
const ejs = require('ejs');
ejs.renderFile('1.html', { name: 'ray' }, (err, data) => {
console.log(data);
})
<% var str="<p></p>"; %>
<%- str %> // ejs 输出 HTML 标签
<% include a.txt %> // 引入 a.txt 中内容