NodeJS 入门篇
开启服务
别的不说,先开机(能正常访问).
hello world !
//引入 http 模块
var http = require("http");
//创建一个服务
var server = http.createServer(function(req,res){
//返回一个结束的输出
res.end("<h1>hello world!</h1>");
});
//监听端口号
server.listen(8888);
console.log("server start at port 8888");
输出访问地址
var http = require("http");
var sum = 0;
var server = http.createServer(function(req,res){
sum++;
//中文输出设置编码,否则写入页面的文字为乱码
res.setHeader("Content-Type","text/html;charset=UTF-8");
res.write("<h1>第"+ sum +"次访问<h1>");
// 输出访问时的IP
res.write(req.connection.remoteAddress);
//控制台输出
console.log(sum);
//结束输出流
res.end("");
});
server.listen(3000);
注意: 输出中文,最好设置一下编码,否则容易乱码。
路由表
根据访问url不同,呈递不同字符串
var http = require("http");
var server = http.createServer(function(req,res){
//路由
//访问主页
if( req.url == "/" ){
res.end("index");
//访问音乐页
}else if( req.url == "/music"){
res.end("music");
//别的一律404
}else{
res.end("404");
}
}).listen(8888);
正则匹配路由获取路由的六位数
var http = require("http");
var a = 0;
var server = http.createServer(function(req,res){
//路由加入正则的匹配
if(/\/n\/([\d]{6})/.test(req.url)){
console.log(a++);
var reg = /\/n\/([\d]{6})/;
var number = reg.exec(req.url)[1];
res.write("<h1>"+ number +"</h1>");
}else{
res.write("404");
}
//最终别忘结束输出流
res.end("");
});
server.listen(8888);
fs
模块
读取文件
作为服务,我们更希望呈递出html页面,而不是简单输出一些字符。
文件结构:
├── demo.js
├── public/
│ ├── index.html
│ ├── css/
│ │ └── css.css
呈递 public文件下的 index.html 页面
var http = require("http"),
fs = require("fs");
http.createServer(function(req,res){
if(req.url == "/"){
//设置文件MIME类型
res.setHeader("content-type","text/html;charset=utf-8");
//fs.读文件("文件路径" , callback(err,data))
fs.readFile("./public/index.html",function(err,data){
if(err){
res.end("文件不存在!");
return;
}
//data 二进制文件 , 使用toString() 转一下
res.end(data.toString());
});
}else{
res.end("404");
}
}).listen(8888);
注意:
- MIME类型,必须与你文件扩展名 一致。
- 读的文件路径 :是相对于你当前 在node运行的.js文件的路径.
- “./” : 表示当前目录下的路径,可以参考一下上面的文件结构.
- node没有像apache那样的自动映射关系,不像apache等服务器输出什么地址 就 罗列地址下的东西。
- 所以你访问的路由地址,是个虚拟的,但是,你在node使用fs
模块去找的这个文件,必须是真实的路径。
css没有生效?
这是读取的html文件,当中引入了一个css文件。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
<!-- 这里的路径 在实际中是 相对于当前html的 真实路径 -->
<link rel="stylesheet" href="css/css.css" />
</head>
<body>
<h1>主页</h1>
</body>
</html>
发现css并没有生效。
h1{
color : red;
}
是什么原因?
打开chrome的NetWork面板 可以看见请求的css.css文件的路径是:
http://lcoalhost:8888/css/css.css
上面说了这是一个虚拟路径,你并没有在node中去读这个文件,
怎么会呈递出来呢?
所以在node中必须真的去找这个文件,才会给你返回。
看代码:
var http = require("http"),
fs = require("fs");
http.createServer(function(req,res){
if(req.url == "/"){
res.setHeader("content-type","text/html;charset=utf-8");
fs.readFile("./public/index.html",function(err,data){
if(err){
res.end("文件不存在!");
return;
}
res.end(data.toString());
});
//这里要于 请求的路径一致
}else if(req.url == "/css/css.css"){
res.setHeader("content-type","text/css;");
//真实去读的时候,还是 当前js文件的相对路径
fs.readFile("./public/css/css.css",function(err,data){
if(err){
res.end("文件不存在!");
return;
}
res.end(data.toString());
});
}else{
res.end("404!");
}
}).listen(8888);console.log("server start");
根据url自动读取
此时你已经明白了,请求的所有文件 都要去手动档去读,累不累!?
如何能像apache一样,自动读取呢?我访问什么路径,就真的自动去这个文件。
var http = require("http");
http.createServer(function(req,res){
//输出我们请求的url
res.end(req.url);
}).listen(8888);
比如我们请求
localhost:8888/
结果是 /
localhost:8888/index.html
/index.html
localhost:8888/index.html
/css/css.css
只要拿到 路径 和 文件名,不就能自动读了吗?
当然你又发现,并不好拿,使用正则去匹配下?
好麻烦,难道只能一辈子只能手动档?
这些还是简单的路由
再来点复杂的呢?
比如加上查询部分(queryString):
localhost:8888/music/index.html?id=123456&name=老王
得到的结果:
/music/index.html?id=123456&name=%E8%80%81%E7%8E%8B
再加上hash部分:
localhost:8888/music/index.html?id=123456&name=老王#66
得到的结果:
/music/index.html?id=123456&name=%E8%80%81%E7%8E%8B
以上能看到,
queryString部分:?id=123456&name=%E8%80%81%E7%8E%8B
hash部分: #66
hash不属于 url 的一部分。
肿么办呢…
没事,兵来将挡,水来土淹没,下面讲解使用正则提炼,
额,不对
使用nodeJS内置模块,直接拿到我们想要的。~ ~
URL
模块
url.parse
var http = require("http"),
url = require("url");
http.createServer(function(req,res){
var urljson = url.parse(req.url,true);//加true 的 query 自动变为对象形式
console.log(urljson);
/* 输入 : http://localhost:8888/music/index.html?id=123456&name=%E8%80%81%E7%8E%8B
* 得到:
* Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?id=123456&name=%E8%80%81%E7%8E%8B',
// query: 'id=123456&name=%E8%80%81%E7%8E%8B', //没有参数 true
query : { id: '123456', name: '老王' } , //此处有true的结果
pathname: '/music/index.html',
path: '/music/index.html?id=123456&name=%E8%80%81%E7%8E%8B',
href: '/music/index.html?id=123456&name=%E8%80%81%E7%8E%8B'
}
*/
res.end("");
}).listen(8888);
得到一个转化后的 Url 对象。
path
querystring
模块
var http = require("http"),
url = require("url"),
path = require("path"),
querystring = require("querystring");
http.createServer(function(req,res){
var urljson = url.parse(req.url); //没有true 使用querystring模块
//得到文件路径
var pathname = urljson.pathname;
console.log(pathname);///music/index.html
//得到扩展名
var extname = path.extname(pathname);
console.log(extname);//.html
//得到查询字符串对象
var qs = urljson.query;//将这里变为kv对儿,更方便我们使用
var qsjson = querystring.parse(qs);
console.log(qsjson);//{ id: '123456', name: '老王' }
res.end("");
}).listen(8888);
静态化文件夹
var http =require('http'),
fs = require('fs'),
url = require('url'),
path = require('path'),
querystring = require('querystring');
var server = http.createServer(function(req,res){
//转url对象
urljson = url.parse(req.url);
//得到querystring对象
qsjson = querystring.parse(urljson.query);
//得到扩展名
extname = path.extname(urljson.pathname);
//路径
var pathname = urljson.pathname;
//public 文件夹静态化
fs.readFile("./public" + pathname, function(err,data){
if(err){
res.end("404");
return;
}
res.end(data);
});
}).listen(8888);
console.log("isOK");
问题:
不能自动识别主页,
识别图片 路径层次问题
var http = require('http'),
fs = require('fs'),
url = require('url'),
path = require('path');
var server = http.createServer((req,res)=>{
//得到用户读取什么
var pathname = url.parse(req.url).pathname;
//得到拓展名
var extname = path.extname(pathname);
if(!extname){
//如果不是以/结尾,此时会造成浏览器识别图片路径层次有问题
//比如http://localhost/b 和 http://localhost/b/ 不一样。
//同样的图片文件 1.jpg
//前者认为是同级目录下的图片,后者认为是b文件夹中的
//验证pathname的最后一位 不等于 /的情况下,补一个/
//apache 也是如此 low..
if(pathname.substr(-1) != "/"){
res.writeHead(302,{"Location": pathname + "/"});
}
pathname += "/index.html";
//304问题
}
fs.readFile("./public" + pathname, (err,data)=>{
if(err){
res.end('404');
return;
}
res.end(data);
});
}).listen(8888);
console.log('server star 8888 port');
问题 :
不同类型文件,没有设置MIME类型。
要根据我读的这个文件类型,自动加上.
//资源管理器
var http = require("http"),
fs = require("fs"),
url = require("url"),
path = require("path"),
querystring = require("querystring");
var server = http.createServer(function(req,res){
//1 - 得到用户读取文件的路径
//http://127.0.0.1/1.jpg myweb会被静态 所以没有myweb/1.jpg
//我们要把 myweb文件夹做成根,myweb是根目录
var pathname = url.parse(req.url).pathname;
//3 - 得到拓展名
var extname = path.extname(pathname);
//6 - 补全首页,如果用户没有输入文件名 则自动补全为主页文件
if(!extname){
//7 - 如果不是以/结尾,此时会造成浏览器识别图片路径层次有问题
//7 - 服务端的 重定向 , 在返回页面之前,补/重定向url
if( pathname.substr(-1) != "/"){
res.writeHead(302,{"Location" : pathname + "/"});
}
pathname += "/index.html";
}
//4 - 准备一个映射关系对儿
var mime = {
".jpg" : "image/jpeg",
".jpeg" : "image/jpeg",
".gif" : "image/gif",
".png" : "image/png",
".html" : "text/html;charset=utf-8",
".css" : "text/css",
".js" : "application/x-javascript"
};
//2 - 真的去读这个文件
fs.readFile("./public/"+pathname,function(err,data){
if(err){
res.end("404");
return;
}
//5 - 检察是否属于我已知的mime类型
if(mime.hasOwnProperty(extname)){
res.setHeader("content-type",mime[extname]);
}
res.end(data);
});
}).listen(8888);
问题:
304 问题,这里不解决了。
关于静态资源可以使用 express .
结束:
对于入门,能更深入的理解,nodejs的路由。