Node(补充)

1、特点:单线程,非阻塞I/o,事件驱动
  • 单线程的好处,减少了内存开销,操作系统的内存换页。
    如果某一个事情,进入了,但是被I/O阻塞了,所以这个线程就阻塞了。
  • 非阻塞I/O, 不会傻等I/O语句结束,而会执行后面的语句。
    非阻塞就能解决问题了么?比如执行着小红的业务,执行过程中,小刚的I/O回调完成了,此时怎么办??
  • 事件机制,事件环,不管是新用户的请求,还是老用户的I/O完成,都将以事件方式加入事件环,等待调度。
2、HTTP模块

Node.js中,将很多的功能,划分为了一个个mudule,大陆的书翻译为模块;台湾的书,翻译为模组。这是因为,有一些程序需要使用fs功能(文件读取功能),有一些不用的,所以为了效率,你用啥,你就require啥。


//这个案例简单讲解http模块
//引用模块
var http = require("http");

//创建一个服务器,回调函数表示接收到请求之后做的事情
var server = http.createServer(function(req,res){
    //req参数表示请求,res表示响应
    console.log("服务器接收到了请求" + req.url);
    res.end();
});
//监听端口
server.listen(3000,"127.0.0.1");

设置一个响应头:

res.writeHead(200,{"Content-Type":"text/plain;charset=UTF8"});
3、模块exports使用

Node.js中,一个JavaScript文件中定义的变量、函数,都只在这个文件内部有效。当需要从此JS文件外部引用这些变量、函数时,必须使用exports对象进行暴露。使用者要用require()命令引用这个JS文件。

foo.js文件中的代码:

    var msg = "你好";
    exports.msg = msg;

msg这个变量,是一个js文件内部才有作用域的变量,如果别人想用这个变量,那么就要用exports进行暴露。

使用者:

    var foo = require("./test/foo.js");
    console.log(foo.msg);

使用者用foo来接收exports对象,也就是说,这里的foo变量,就是文件中的exports变量。
js文件中,可以用exports暴露很多东西,比如函数、变量。

var msg = "你好";
var info = "呵呵";
function showInfo(){
  console.log(info);
}
exports.msg = msg;
exports.info = info;
exports.showInfo = showInfo;

在使用者中,只需要require一次。

可以将一个JavaScript文件中,描述一个类。用module.export = 构造函数名;的方式向外暴露一个类。

也就是说,js文件和js文件之间有两种合作的模式:
1) 某一个js文件中,提供了函数,供别人使用。 只需要暴露函数就行了; exports.msg=msg;
2) 某一个js文件,描述了一个类。 module.exports = People;

4、模块
  • 如果在require命令中,这么写:
    var foo = require("foo.js"); //没有写./, 所以不是一个相对路径。是一个特殊的路径
    那么Node.js将该文件视为node_modules目录下的一个文件
  • node_modules文件夹并不一定在同级目录里面,在任何直接祖先级目录中,都可以。甚至可以放到NODE_PATH环境变量的文件夹中。这样做的好处稍后你将知道:分享项目的时候,不需要带着modules一起给别人。
  • 每一个模块文件夹中,推荐都写一个package.json文件,这个文件的名字不能改。node将自动读取里面的配置。有一个main项,就是入口文件:
1   {
2     "name": "kaoladebar",
3     "version": "1.0.1",
4     "main" : "app.js"
5   }

package.json文件,要放到模块文件夹的根目录去。

5、路径
  • require()中的路径,是从当前这个js文件出发,找到别人。而fs是从命令提示符找到别人。例如,桌面上有一个a.js, test文件夹中有b.js、c.js、1.txt.
    a要引用b:
    var b = require(“./test/b.js”);

b要引用c:

    var b = require(“./c.js”);

但是,fs等其他的模块用到路径的时候,都是相对于cmd命令光标所在位置。所以,在b.js中想读1.txt文件,推荐用绝对路径:

1   fs.readFile(__dirname + "/1.txt",function(err,data){
2       if(err) { throw err; }
3       console.log(data.toString());
4   });
6、post请求提交

静态页面:form.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://127.0.0.1/dopost" method="post">
    <p>
        姓名:<input type="text" name="name">
    </p>
    <p>
        性别:
        <input type="radio" name="sex" value="男">男
        <input type="radio" name="sex" value="女">女
    </p>
    <p>
        爱好:
        <input type="checkbox" name="hobby" value="足球">足球
        <input type="checkbox" name="hobby" value="睡觉">睡觉
        <input type="checkbox" name="hobby" value="吃饭">吃饭
    </p>
    <p>
        <input type="submit">
    </p>
</form>
</body>
</html>

服务端:form.js

/**
 * Created by 黄森 on 2017/7/16.
 */
var http = require("http");
var querystring = require("querystring");

var server = http.createServer(function (req, res) {
    //如果你的访问地址是这个,并且请求类型是post
    if (req.url == "/dopost" && req.method.toLowerCase() == "post") {
        var allData = '';
        //下面是post请求接收的一个公式
        //node为了追求极致,它是一个小段一个小段接收的。
        //接受了一小段,可能就给别人去服务了。防止一个过大的表单阻塞了整个进程
        req.addListener("data", function (chunk) {
            allData += chunk;
        });
        //全部传输完毕
        req.addListener("end", function () {
            var datastring = allData.toString();
            res.end('success');
            //将datastring转为一个对象
            var dataObj = querystring.parse(datastring);
            console.log(dataObj);
            console.log("姓名:" + dataObj.name);
            console.log("性别:" + dataObj.sex);
        })
    }
});
server.listen(80, "127.0.0.1");

如果表单中有checkbox,那么将会转换成数组输出,再去遍历:

提交表单
输出结果
7、文件上传

只要涉及文件上传,那么form标签要加一个属性:

<form action="http://127.0.0.1/dopost" method="post" enctype="multipart/form-data">

静态页面:form.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://127.0.0.1/dopost" method="post" enctype="multipart/form-data">
    <p>
        姓名:<input type="text" name="name">
    </p>
    <p>
        性别:
        <input type="radio" name="sex" value="男">男
        <input type="radio" name="sex" value="女">女
    </p>
    <p>
        爱好:
        <input type="checkbox" name="hobby" value="足球">足球
        <input type="checkbox" name="hobby" value="睡觉">睡觉
        <input type="checkbox" name="hobby" value="吃饭">吃饭
    </p>
    <p>
        图片:
        <input type="file" name="tupian" />
    </p>
    <p>
        <input type="submit">
    </p>
</form>
</body>
</html>

服务端代码:upload.js

/**
 * Created by 黄森 on 2017/7/16.
 */
var http = require("http");
var util = require("util");//工具模块
var formidable = require('formidable');//文件上传模块

var server = http.createServer(function (req, res) {
    //如果你的访问地址是这个,并且请求类型是post
    if (req.url == "/dopost" && req.method.toLowerCase() == "post") {
        //Creates a new incoming form.
        var form = new formidable.IncomingForm();
        //设置文件上传存放地址
        form.uploadDir = "./uploads";
        //执行里面的回调函数的时候,表单已经全部接收完毕了。
        form.parse(req, function(err, fields, files) {
            if(err){
                throw err;
            }
            console.log(fields);
            console.log(files);
            console.log(util.inspect({fields: fields, files: files}));
            //所有的文本域、单选框,都在fields存放;
            //所有的文件域,files
            res.writeHead(200, {'content-type': 'text/plain'});

            res.end("成功");
        });
    }
});
server.listen(80, "127.0.0.1");

在这里上传上去的图片是没有扩展名的,所以下面我们需要进行文件上传改名的操作:

/**
 * Created by 黄森 on 2017/7/16.
 */
var http = require("http");
var util = require("util");
var formidable = require('formidable');
var fs = require("fs");
var sd = require("silly-datetime");
var path = require("path");

var server = http.createServer(function (req, res) {
    //如果你的访问地址是这个,并且请求类型是post
    if (req.url == "/dopost" && req.method.toLowerCase() == "post") {
        //Creates a new incoming form.
        var form = new formidable.IncomingForm();
        //设置文件上传存放地址
        form.uploadDir = "./uploads";
        //执行里面的回调函数的时候,表单已经全部接收完毕了。
        form.parse(req, function (err, fields, files) {
            if (err) {
                throw err;
            }
            // 时间
            var ttt = sd.format(new Date(), 'YYYYMMDDHHmmss');
            // 随机数
            var ran = parseInt(Math.random() * 89999 + 10000);
            // 扩展名
            var extname = path.extname(files.tupian.name);

            //执行改名
            var oldpath = __dirname + "/" + files.tupian.path;
            var newpath = __dirname + "/uploads/" + ttt + ran + extname;

            //改名
            fs.rename(oldpath,newpath,function (err) {
                if(err){
                    throw Error("改名失败");
                }
                res.writeHead(200, {'content-type': 'text/plain'});
                res.end("成功");
            });
            //所有的文本域、单选框,都在fields存放;
            //所有的文件域,files
            res.writeHead(200, {'content-type': 'text/plain'});
            res.end("成功");
        });
    }
});
server.listen(80, "127.0.0.1");
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,454评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,553评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,921评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,648评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,770评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,950评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,090评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,817评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,275评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,592评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,724评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,409评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,052评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,815评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,043评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,503评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,627评论 2 350

推荐阅读更多精彩内容

  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宫若石阅读 1,064评论 0 1
  • Node.js是目前非常火热的技术,但是它的诞生经历却很奇特。 众所周知,在Netscape设计出JavaScri...
    w_zhuan阅读 3,610评论 2 41
  • 个人入门学习用笔记、不过多作为参考依据。如有错误欢迎斧正 目录 简书好像不支持锚点、复制搜索(反正也是写给我自己看...
    kirito_song阅读 2,458评论 1 37
  • Node.js是目前非常火热的技术,但是它的诞生经历却很奇特。 众所周知,在Netscape设计出JavaScri...
    Myselfyan阅读 4,066评论 2 58
  • 不知从何时,开始对自己的梦境在意起来。 对其在意,应该是源于它给我的困扰,曾经看过一篇文章谈过说,早上起来能记住的...
    暗影生异彩阅读 230评论 0 0