const http=require("http");
var server = http.createServer(function (req, res) {
switch (req.url) {
case "/index":
res.write("This is index page");
break;
case "/about":
res.write("This is a about page");
break;
default:
res.write("404 Not Found");
break;
}
res.end();
});
server.listen("8080");
执行node server.js
在浏览器中输入:[http://localhost:8080/about]
在根目录新建“www”文件夹,文件夹中新建“index.html”和“about.html”文件
const http = require("http");
const fs = require("fs");
var server = http.createServer(function (req, res) {
var file_path = "./www" + req.url;
fs.readFile(file_path, function (err, data) {
if (err) {
res.write("404");
} else {
res.write(data);
}
res.end();
});
});
server.listen("8080");
执行node server.js
在浏览器中输入:http://localhost:8080/about.html
便可访问www文件夹下的about.html
(PS.console.log(req.url); // '/adout.html'
)
未使用时,如何获取url中的参数?
先在“www”文件中中创建index.html,
PS.采用了“get”方法
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>indextitle>
head>
<body>
<form action="http://localhost:8080/result" method="get">
姓名:<input type="text" name="username"/><br>
密码:<input type="password" name="password"/><br>
<input type="submit" value="提交"/>
form>
body>
html>
server.js文件如下
const http = require("http");
const fs = require("fs");
var server = http.createServer(function (req, res) {
var file_path = "./www" + req.url;
if (req.url == "/index.html") {
fs.readFile(file_path, function (err, data) {
if (err) {
res.write("404");
} else {
res.write(data);
}
res.end();
});
} else {
r = {};
if (req.url.indexOf("?") != -1) {
// /result?username=aaa&password=aaa
var urlParams = req.url.split("?")[1];
var kvs = urlParams.split("&");
for (var i = 0; i < kvs.length; i++) {
var temp = kvs[i].split("=");
r[temp[0]] = temp[1];
}
res.write(r["username"] + ":" + r["password"]);
console.log(r);
}
res.end();
}
});
server.listen("8080");
若使用querystring模块,则
r = {};
if (req.url.indexOf("?") != -1) {
// /result?username=aaa&password=aaa
var urlParams = req.url.split("?")[1];
r = querystring.parse(urlParams);
res.write(r["username"] + ":" + r["password"]);
console.log(r);
}
res.end();
其中,querystring.parse(urlParams);
这个方法,
可以将
username=aa&password=aa
格式化为
{username:'aa',password:'aa'}
接上面的例子,如果不使用querystring,可以使用url模块来读取url中的参数
r = {};
var o = urlLib.parse(req.url, true);
res.write(o.query["username"]+":"+o.query["password"]);
console.log(o);
res.end();
其中console.log(o);
的结果如下:
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?username=saa&password=sa',
query: { username: 'saa', password: 'sa' },
pathname: '/result',
path: '/result?username=saa&password=sa',
href: '/result?username=saa&password=sa' }
如果urlLib.parse(req.url, true)不添加参数“true”,会报错
TypeError: Cannot read property 'username' of null
原因是:
query: 'username=saa&password=sa',
query对应的值就不是对象的样子,而是用&连接起来的一个字符串,就是最原始的那个
mkdir simple_server_practice
cd simple_server_practice
补充:
上面的表单采用的是get方法,如为post方法,则
var str = "";
req.on("data", function (data) {
str +=data;
console.log(str); //username=sa&password=sa
});
req.on("end", function () {
var r = querystring.parse(str);
console.log(r); //{ username: 'sa', password: 'sa' }
});
res.end();
post的内容其实是分批传输,而不是一次性传输(可以尝试大数据传输)
上述学到的模块都为系统模块,当然不止是只有上面那种。
Node.js除了系统模块之外还有自定义模块。
在引用模块的时候,假设自定义了一个模块,在根目录中创建a.js,引用时
cost http=require("http"); //引用系统模块
const a=require("./a.js"); //引用当前目录中的自定义模块,需要加上“./”,可省略“.js”
我们定义一个模块,其实最核心的是利用exports暴露出去,比如在1.js里面:
exports.a = 11;
exports.b = 22;
然后在需要引用该模块的地方,这么使用即可:
const t1 = require('./1.js');
console.log(t1.a,t1.b);
但是,这种模块里内容的输出要写很多个exports,有另一个方法是:
module.exports = {
a:111,
b:222
}
引用模块需要注意的地方总结:
如果require括号中的内容带有“./”,则require的内容会从当前目录中找;
如果不带“./”,则,require的内容会先从系统模块中找,如果未找到,会从node_modules这个文件夹中寻找。
首先安装
npm install express
创建一个服务器,并对比一下原生访问页面的代码:
const express=require("express");
var server=express();
server.use("/a.html", function (req, res) {
res.send("aaa");
res.end();
})
server.use("/b.html", function (req, res) {
res.send("bbb");
res.end();
})
server.listen("8080");
其中,express中保留了res.write(),增加了res.send()方法,write()方法只能读取string和buffer类型的数据,send()是write()的增强版。
另外,get、post请求的接受方法
//适用于get
server.get("", function (req, res) {
...
})
//适用于post
server.post("", function (req, res) {
...
})
//两者都适用
server.use("", function (req, res) {
...
})
1.express-static:处理静态文件
const expressStatic=require("express-static");
...
server.use(expressStatic("文件夹名字"));
//eg.访问localhost:8080/a.html,则会在文件夹中寻找是否有a.html,然后显示出来
2.获取数据
(2)get方法
console.log(req.query); //{ username: 'sa', password: 'sa' }
(2)post方法
首先安装
npm install body-parser
const bodyParser = require("body-parser");
...
server.use(bodyParser.urlencoded({}));
server.use("/", function (req, res) {
console.log(req.body);
})
3.cookie 和 session
(1)关于cookie
创造一个cookie
const express=require("express");
var server=express();
server.listen(8080);
server.use("/",function(req,res){
res.cookie("username","sa",{path:"/",maxAge:30*24*3600*1000});
// path表示哪个路径下可以读取这个cookie,后面的参数是过期时间,毫秒
res.send("ok");
})
其次是读取cookie
const express=require("express");
// 先安装cookie-parser
const cookieParser = require('cookie-parser');
var server=express();
server.listen(8080);
server.use(cookieParser());
server.use("/",function(req,res){
console.log(req.cookies);
res.send("ok");
});
对cookie进行签名加密
还用req.cookies的话,得到的值就是签名后的值,但是我们想要的是那个被签名之前的值,比如sa,那么需要用req.signedCookies。
const express=require("express");
const cookieParser = require('cookie-parser');
var server=express();
server.listen(8080);
server.use(cookieParser('my_secret_key_is_123456'));
server.use("/",function(req,res){
res.cookie("username","sa",{path:"/",maxAge:30*24*3600*1000,signed:"true"});
// 如果cookie是被签名果的,那么我们获取的时候不能直接用req.cookies(它是空的),所有的数据在req.signedCookies里面
console.log(req.signedCookies); //加密前
res.send("ok");
});
最后是清除cookie:
res.clearCookie["xxx"];
(2)关于session
写入session
const express=require("express");
const cookieParser = require('cookie-parser');
const cookieSession = require('cookie-session');
var server=express();
server.listen(8080);
var keyArr = []
for (var i = 0; i < 10000; i++) {
keyArr.push('sig_' + Math.random());
}
server.use(cookieParser());
server.use(cookieSession({
// 存在浏览器端的cookie的名字
name:'mySess',
keys:[keyArr],
maxAge:30*24*3600*1000
}));
server.use('/',function(req,res){
if (req.session['username']==null) {
req.session['username']='eric';
res.send('第一次登录');
}else{
res.send('你已经登录了');
}
});
最后清除session
delete req.session['xxx'];
首先安装npm install ejs
在www文件夹下新建index.ejs文件
<html>
<head>
<meta charset="utf-8">
<title>indextitle>
head>
<body>
<p><%= content.name %>p>
<ul>
<% for(var i=0;i
<li><%= content.titles[i] %>li>
<% } %>
ul>
body>
html>
修改server.js
const ejs=require('ejs');
ejs.renderFile('./www/index.ejs',{
content:{
name:'news',
titles:['title1','title2','title3','title4'],
}
},function(err,data){
console.log(data);
});
首先安装npm instal multer
然后在www文件夹中新建upload文件夹
之后在www文件中新建index.html,内容如下:(注意:enctype="multipart/form-data"
)
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传测试title>
head>
<body>
<form action="http://localhost:8080/upload" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username"><br>
请上传头像:<input type="file" name="avatar"><br>
<input type="submit" value="提交">
form>
body>
html>
(1)单个文件上传
server.js内容如下 :
const express = require('express');
const multer = require('multer');
const expressStatic = require('express-static');
// 文件上传存储目录
var upload = multer({dest:'./www/upload'});
var server = express();
server.post('/upload',upload.single('avatar'),function(req,res){
// single需要指定name,下面接收也只用file
console.log(req.file);
// 还可以接收一并过来的body数据,multer其实包含了之前的解析post里body的功能
console.log(req.body);
res.send('upload success.');
});
server.use(expressStatic('./www'));
server.listen(8080);
控制台输出的结果如下:
Error: ENOENT: no such file or directory, stat 'E:\myproject\node_pratice\Simple_server_practice\www\favicon.ico'
{ fieldname: 'avatar',
originalname: '117.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: './www/upload',
filename: 'a6329909deea5b87b549d9b5f8df3986',
path: 'www\\upload\\a6329909deea5b87b549d9b5f8df3986',
size: 41466 }
{ username: 'sa' }
Error: ENOENT: no such file or directory, stat 'E:\myproject\node_pratice\Simple_server_practice\www\favicon.ico'
在upload文件夹中,会出现上传的内容,名字为“a6329909deea5b87b549d9b5f8df3986”,但无后缀名。解决方法如下:
修改server.js
const express = require('express');
const multer = require('multer');
const expressStatic = require('express-static');
const fs = require("fs");
const pathLib = require("path");
// 文件上传存储目录
var upload = multer({dest:'./www/upload'});
var server = express();
server.post('/upload',upload.single('avatar'),function(req,res){
// single需要指定name,下面接收也只用file
//console.log(req.file);
// 还可以接收一并过来的body数据,multer其实包含了之前的解析post里body的功能
//console.log(req.body);
//上传前的文件名:117.jpg
var name = req.file.originalname;
//上传后的文件名,无后缀:a6329909deea5b87b549d9b5f8df3986
//var oldname = req.file.filename;
//上传后的文件存放路径:www\\upload\\a6329909deea5b87b549d9b5f8df3986
var oldpath = req.file.path;
//获取上传前的文件扩展名:jpg
var ext = pathLib.parse(name).ext;
//新名字为:a6329909deea5b87b549d9b5f8df3986.jpg
//var newname = oldname + ext;
//新路径:www\\upload\\a6329909deea5b87b549d9b5f8df3986.jpg
var newpath = oldpath + ext;
//修改文件名
fs.rename(oldpath, newpath);
res.send('upload success.');
});
server.use(expressStatic('./www'));
server.listen(8080);
(2)多个同名文件上传
修改index.html,多增加上传图片的按钮
请上传头像1:type="file" name="avatar">
请上传头像2:type="file" name="avatar">
请上传头像3:type="file" name="avatar">
修改server.js
const express = require('express');
const multer = require('multer');
const expressStatic = require('express-static');
const fs = require("fs");
const pathLib = require("path");
// 文件上传存储目录
var upload = multer({dest:'./www/upload'});
var server = express();
server.post('/upload',upload.array('avatar',3),function(req,res){
// 因为是single,所以是一个,需要指定name,下面接收也只用file
console.log(req.files);
for (var i = 0; i var newName = req.files[i].path + pathLib.parse(req.files[i].originalname).ext;
fs.rename(req.files[i].path,newName,function(err){
if (err) {
console.log("rename failure.");
}else{
console.log("rename success.");
}
});
}
console.log(req.body);
res.send('upload success.');
});
server.use(expressStatic('./www'));
server.listen(8080);
(3)不同名的多文件上传
修改index.html
用户名:type="text" name="username">
请上传头像1:type="file" name="avatar">
请上传头像2:type="file" name="avatar">
请上传头像3:type="file" name="avatar">
请上传背景:type="file" name="bg">
修改server.js
server.post('/upload',upload.fields([{name:'avatar',maxCount:3},{name:'bg',maxCount:1}]),function(req,res){
console.log(req.files);
for(var i=0;i<req.files['avatar'].length;i++){
var newName = req.files['avatar'][i].path + pathLib.parse(req.files['avatar'][i].originalname).ext;
fs.rename(req.files['avatar'][i].path,newName,function(err){
if(err){
console.log('upload failure.')
}else{
console.log('upload success.')
}
});
}
var newName = req.files['bg'][0].path + pathLib.parse(req.files['bg'][0].originalname).ext;
fs.rename(req.files['bg'][0].path,newName,function(err){
if (err) {
console.log('upload failure.')
}else{
console.log('upload success.')
}
});
console.log(req.body);
res.send('upload success.');
});
新建views文件夹,并在其中新建1.ejs
1.ejs如下:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传测试title>
head>
<body>
Hello,<%=name %>
body>
html>
修改server.js
const express = require('express');
const consolidate = require("consolidate");
var server = express();
//设置输出格式:输出html格式
server.set("view engine", "html");
//指定引用的模板存放的位置:存放在"./vide"中
server.set("views", "./views");
//用什么样的解析式:用ejs解释器去解释为html
server.engine("html", consolidate.ejs);
server.get("/index", function (req, res) {
res.render("1.ejs", {name:"sa"});
})
server.use(expressStatic('./www'));
server.listen(8080);
router是express提供的
const express = require('express');
var server = express();
// routerUser相当于创建的一个子server
var routerUser = express.Router();
// 然后把这个子server和某个路径绑定
server.use('/user',routerUser);
// 然后基于这个子server来写,才能拦截这个路径的所有请求
// http://localhost:8080/user/list
routerUser.get('/list',function(req,res){
res.send("user list");
});
// http://localhost:8080/user/detail
routerUser.get('/detail',function(req,res){
res.send("user detail");
})
var routerPost = express.Router();
server.use('/post',routerPost);
// http://localhost:8080/post/list
routerPost.get('/list',function(req,res){
res.send("post list");
})
// http://localhost:8080/post/detail
routerPost.get('/detail',function(req,res){
res.send("post detail");
});
server.listen(8080);
npm install mysql
链接数据库
const mysql = require('mysql');
var db = mysql.createConnection({
host:'localhost',
user:'root',
password:'root',
database:'nodejs'
});
操作模板
db.query(mql语句,(err,data)=>{
if(err)
console.log("Error:" + err);
else
console.log(JSON.stringify(data));
});
db.query("select * from N_USER;",(err,data)=>{
if(err)
console.log("Error:" + err);
else
console.log(JSON.stringify(data));
});
参考教程:【教程】Javascript之Node.JS从理论到实战(石川)
参考博客:Node.js