NodeJS 入门

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的路由。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值