1.运行node文件
node D:\wamp\www\node_middle\demo1\helloworld.js
也可以先进入文件目录下 在用 node helloworld运行
nodejs是服务器的程序,写的 js语句,都将运行在服务器上,返回给客户端的,都是已经处理好的纯html 代码(可以说node是一个js的执行环境)
如果服务器端的内同有修改,则需要重启服务器才能实现同步更新
2.创建一个服务器
var http = require('http')
var server = http.createServer(function(request,response){
response.writeHead(200,{'Content-Type':'text/html;charset=UTF-8'});
response.end('这是我的第一个服务器')
});
//监听服务器
server.listen(9999,function(error){
if(error){
console.log(error)
}else {
console.log('端口号为9999的服务器已经成功启动!')
}
});
nodejs没有根目录,没有web容器,只能根据路由编辑自己的容器,但是好处是node路由名字可以随便取名,跟要访问的页面可以没有任何关系。如果看到一个url地址:http://127.0.0.1:9999/index,不一定就有一个文件夹叫index,可能/index是同目录下的01.html。好处就是你从访问的地址中不能判断出页面是放在哪个文件夹中的。传统的服务器是有web容器的,页面只要一放入服务器中就能访问。容易辨别目录结构。node需要的每一个文件都需要提前去读取。
http模块
nodejs 有很多功能,划分为了许多module,也就是我们说的模块,根据不同的需求,局require(‘模块’)
var http = require('http');
var server = http.createServer(req,res){
res.writeHead(200,{'Content-type':'text/html;charset=utf8'})//设置响应头的状态码和编码
console.log(req.url)//获取请求的路径
res.write('这个方法是写入的')
res.end();//这个方法是必须要写的 代表响应结束
//需要注意的是 write 和 end方法中的参数只能是字符串或者是buffer
}
server.listen(3000,'127.0.0.1')
request中能够使用的东西
req.url //获取请求中的url地址
var http = require('http')
var url = require('url');
http.createServer(function(req,res){
var path = req.url;//获取整个地址 eg:http://127.0.0.1:9999/wwdiid/ddfdfd/html.html?id=32&age=23
var query=url.parse(path,true).query//添加一个参数为true 获取传过来的是一个对象{id:32,age:23}
console.log(url.parse(path).pathname)//获取网址的目录地址 /wwdiid/ddfdfd/html.html
console.log(url.parse(path).query)//获取地址后面传的参数 id=32
console.log(query.age)
res.end()
}).listen(9999,'127.0.0.1')
**利用nodejs模拟表单的提交数据**
html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模拟表单的提交</title>
</head>
<body>
<form action="http://127.0.0.1:9999/" method="GET">
姓名:<input type="text" name="name"/><br>
年龄:<input type="text" name="age"/><br>
性别<input type="radio" name="sex" value="man"/>男
<input type="radio" name="sex" value="women"/>女
<br>
<input type="submit">
</form>
</body>
</html>
nodejs代码:
var http = require('http')
var url = require('url');
http.createServer(function(req,res){
var path = req.url;//获取整个地址 eg:http://127.0.0.1:9999/wwdiid/ddfdfd/html.html?id=32&age=23
var url_parse=url.parse(path,true)//添加一个参数为true 获取传过来的是一个对象{id:32,age:23}
var query=url_parse.query
var name=query.name;
var age=query.age
var sex = query.sex
console.log(name)
console.log(age)
console.log(sex)
res.end()
}).listen(9999,'127.0.0.1')
fs模块的操作
创建一个文件夹
var http = require('http')
var fs = require('fs')
var server = http.createServer(function(req,res){
//res.writeHead(200,{"Content-Type":"text/html;charset=utf8"})
fs.mkdir("./aaa",function(err,data){
console.log('文件夹创建成功')
});
res.end()
});
server.listen(9999,'127.0.0.1');
遍历一个文件夹下的文件名(包括文件夹名和文件名)
var http = require('http')
var fs= require('fs')
var server = http.createServer(function(req,res){
if(req.url=='/favicon.ico'){
return;
}
//遍历iteraor
fs.readdir('./aaa/',function(err,files){
//files是一个存放文件名的数组
var wenjianjian =[]; //用来存放遍历的文件夹
//迭代器就是强行把异步函数变成同步函数
//1.做了 再做2
(function iterator(i){
if (i == files.length) {
console.log(wenjianjian)
return;
}
fs.stat('./aaa/'+files[i],function(err,stats){
if (stats.isDirectory()) {
wenjianjian.push(files[i])
}
iterator(i+1);
});
})(0);
});
res.end();
});
server.listen(9999,'127.0.0.1')
nodejs特点
单线程、Non-blocking I/O、Event Driven。 实际上是一个特点。
首先,Node不为每个用户开辟一个线程,所以非常极端的选择了单线程。单线程,要照顾所有的用户,那么就必须有非阻塞I/O,否则一个人的I/O就把别人、自己都阻塞了。一旦有非阻塞I/O,一个人如果I/O去了,就会放弃CPU的使用权,换成另一个人使用CPU(或者执行此人后面的语句)。所以CPU的利用率100%。第一个人I/O结束了,就要用事件来通知线程,执行回调函数。此时必须有事件环,就有一个排队调度机制。Node中有超过半数的C++代码,在搭建事件环。
Node.js和别的老牌3P不一样: 1)
没有自己的语法,使用V8引擎,所以就是JS。V8引擎解析JS的,效率非常高,并且V8中很多东西都是异步的。Node就是将V8中的一些功能自己没有重写(别人做了,自己就站在巨人肩膀上),移植到了服务器上。
2) 没有web容器,就是安装配置完成之后,没有一个根目录。
nodejs的模块化
狭义的说,每一个JavaScript文件都是一个模块;而多个JavaScript文件之间可以相互require,他们共同实现了一个功能,他们整体对外,又称为一个广义上的模块。
Node.js中,一个JavaScript文件中定义的变量、函数,都只在这个文件内部有效。当需要从此JS文件外部引用这些变量、函数时,必须使用exports对象进行暴露。使用者要用require()命令引用这个JS文件。
01.js文件
var name='xiaoming';
var age = 23;
exports.module={name:name,age:age}```
02.js
var foo = require('./01.js');
console.log(foo.name)
console.log(foo.age)```
一个JavaScript文件,可以向外exports无数个变量、函数。但是require的时候,仅仅需要require这个JS文件一次。使用的它的变量、函数的时候,用点语法即可。所以,无形之中,增加了一个顶层命名空间。
可以将一个JavaScript文件中,描述一个类。用
module.export = 构造函数名;
的方式向外暴露一个类。
也就是说,js文件和js文件之间有两种合作的模式:
- ) 某一个js文件中,提供了函数,供别人使用。 只需要暴露函数就行了; exports.msg=msg;
- )
某一个js文件,描述了一个类。 module.exports = People;
如果在require命令中,这么写:
var foo = require("foo.js"); //没有写./, 所以不是一个相对路径。是一个特殊的路径
那么Node.js将该文件视为node_modules目录下的一个文件
我们可以使用文件夹来管理模块,比如
var bar = require("bar");
那么Node.js将会去寻找node_modules目录下的bar文件夹中的index.js去执行。
每一个模块文件夹中,推荐都写一个package.json文件,这个文件的名字不能改。node将自动读取里面的配置。有一个main项,就是入口文件:
{
"name": "kaoladebar",
"version": "1.0.1",
"main" : "app.js"
}
package.json文件,要放到模块文件夹的根目录去。
post表单传输
1var alldata = “”;
2 //下面是post请求接收的一个公式
3 //node为了追求极致,它是一个小段一个小段接收的。
4 //接受了一小段,可能就给别人去服务了。防止一个过大的表单阻塞了整个进程
5 req.addListener("data",function(chunk){
6 alldata += chunk;
7 });
8 //全部传输完毕
9 req.addListener("end",function(){
10 console.log(alldata.toString());
11 res.end("success");
});
原生写POST处理,比较复杂,要写两个监听。文件上传业务比较难写。
所以,用第三方模块。formidable。
只要涉及文件上传,那么form标签要加一个属性:
<form action="http://127.0.0.1/dopost" method="post" enctype="multipart/form-data">
nodejs实现提交表单的数据
html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>表单上传</title>
</head>
<body>
<form action="http://127.0.0.1:9999/dopost" method="post" >
姓名:<input type="text" name="name"><br>
年龄:<input type="number" name="age"><br>
性别:<input type="radio" name="sex" value="man">男<input type="radio" name="sex" value="women">女</br>
爱好:<input type="checkbox" name="checkbox" value="篮球">篮球<input type="checkbox" name="checkbox" value="足球">足球
<input type="checkbox" name="checkbox" value="lol">lol<br>
<input type="file" name="file"><br>
<input type="submit"></input>
</form>
</body>
</html>
node文件
var http = require('http');
var querystring = require('querystring');
var fb = require('formidable');
var server = http.createServer(function(req,res){
if(req.url=='/dopost'&& req.method.toLowerCase() == 'post'){
var alldata ='';
req.on('data',function(chunk){
alldata+=chunk;
})
req.on('end', function () {
var datastring = alldata.toString()//得到的是一个字符串 需要解析
var obj= querystring.parse(datastring);//定义一个对象来存放解析后的结果
console.log(obj.name);
console.log(obj.age);
console.log(obj.sex);
console.log(obj.checkbox[0]);
console.log(obj.file);//需要注意的是文件上传只是取到了一个文件名,文件本身是没有上传的。如果需要上建议使用nodejs的formidable模块
res.end('数据传递成功')
})
}
})
server.listen(9999,'127.0.0.1');
文件上传后改名
利用fs模块的rename模块更改
require('fs').rename('./01.txt','./02.txt')//使用相对路径 02会覆盖掉01
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<form action="http://127.0.0.1:9999/dopost" method="post" enctype="multipart/form-data" >
姓名:<input type="text" name="name"><br>
年龄:<input type="number" name="age"><br>
性别:<input type="radio" name="sex" value="man">男<input type="radio" name="sex" value="women">女</br>
爱好:<input type="checkbox" name="checkbox" value="篮球">篮球<input type="checkbox" name="checkbox" value="足球">足球
<input type="checkbox" name="checkbox" value="lol">lol<br>
<input type="file" name="file"><br>
<input type="submit"></input>
</form>
</body>
</html>
node.js
/**
* Created by xc on 2017/3/1.
*/
var http = require('http');
var querystring = require('querystring');
var formidable = require('formidable');
var util = require('util');
var fs = require('fs');
var sd = require('silly-datetime');
var path = require('path');
var server = http.createServer(function(req,res){
if(req.url=='/dopost'&& req.method.toLowerCase() == 'post'){
var form = new formidable.IncomingForm();
form.uploadDir = './uploads';//设置文件上传地址
form.parse(req, function(err, fields, files) {
res.writeHead(200, {'content-type': 'text/plain'});
//res.write('received upload:\n\n');
//res.end(util.inspect({fields: fields, files: files}));
var ttt=sd.format( new Date(),'YYYYMMDDHHmm');
var ran = parseInt(Math.random()*89999+10000);
console.log(ttt)
//获取扩展名
var extname = path.extname(files.file.name);
//执行改名
var oldpath = __dirname+'/'+files.file.path;
//新的路径由三个部分组成
var newpath = __dirname+'/uploads/'+ttt+ran+extname;
fs.rename(oldpath,newpath,function(err){
if (err){
console.log('改名失败');
}
res.end('改名成功')
});
console.log(util.inspect({fields:fields,files:files}));
});
}
})
server.listen(9999,'127.0.0.1');
模板引擎
1<a href="<%= url %>"><img src="<%= imageURL %>" alt=""></a>
数据绑定,就成为一个完整的html字符串了。
前台的模板,我们现在要学习的是后台的模板。
后台模板,著名的有两个,第一个叫做ejs; 第二个叫做jade。
是npm第三方包。
后台模板引擎 ejs
index.ejs文件:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模板引擎</title>
</head>
<body>
<h1>每一周有<%= a %>天</h1>
<ul>
<%for (var i= 0;i< fruit.length;i++){%>
<li> <%= fruit[i] %> </li>
<%}%>
</ul>
</body>
</html>
index.js文件
var http = require('http');
var ejs = require('ejs');
var fs = require('fs');
var server = http.createServer(function(req,res){
fs.readFile('./ejs.ejs',function(err,data){
if (err){
throw err;
}
var obj ={
a:7,
fruit:['苹果','香蕉','西瓜']
}
var st = data.toString();
var html = ejs.render(st,obj);
res.writeHead(200,{"Content-Type":"text/html;charset=utf8"})
res.end(html);
})
})
server.listen(9999,'127.0.0.1')
效果图: