├── .babelrc
├── .gitignore
├── 1.jpg
├── README.md
├── favicon.ico
├── fileServer.js
├── learn
├── index.html
├── output.txt
├── style.css
└── test.txt
├── lib
├── database.js
├── index.js
├── requestHandlers.js
├── router.js
└── server.js
├── package.json
└── src
├── database.js
├── index.js
├── requestHandlers.js
├── router.js
└── server.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [ "es2015", "stage-0", "stage-1", "stage-2", "stage-3" ],
3 | "plugins": [
4 | "transform-strict-mode",
5 | "transform-es2015-modules-commonjs",
6 | "transform-es2015-spread",
7 | "transform-es2015-destructuring",
8 | "transform-es2015-parameters"
9 | ],
10 | }
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 |
--------------------------------------------------------------------------------
/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damonare/node-sample/99cd5a31823090751d0c6469202d11f3c5604e02/1.jpg
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # node-sample
2 |
3 | > 本node应用实现了一个文件上传功能,涉及知识点有:服务端JavaScript、函数式编程、阻塞与非阻塞、回调、事件、内部和外部模块等等。可谓麻雀虽小,五脏俱全。
4 |
5 | - 文件上传显示在本地浏览器(允许用户上传图片,并将该图片在
6 | 浏览器中显示出来)
7 | - 平时的部分测试代码
8 | - 充分添加注释,有没说清楚欢迎联系我jztan1996@gmail.com或是直接提issue
9 | - lib文件夹内为babel转码后的ES5代码,src为ES6语法版本
10 |
11 | **操作方法**
12 |
13 | ```
14 | //安装依赖
15 | npm install
16 | //运行应用
17 | node index
18 | ```
19 |
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/damonare/node-sample/99cd5a31823090751d0c6469202d11f3c5604e02/favicon.ico
--------------------------------------------------------------------------------
/fileServer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | import fs from 'fs';
3 | import http from 'http';
4 | import path from 'path';
5 | import url from 'url';
6 | import koa from 'koa';
7 |
8 | const workDir = path.resolve('.');
9 | const hostname = '127.0.0.1';
10 | const port = 4000;
11 |
12 | console.log('Static root dir: ' + workDir);
13 | //创建文件服务器
14 | const server = http.createServer((request, response) => {
15 | const pathname = url.parse(request.url).pathname;
16 | const filePath = path.join(workDir, pathname);
17 | fs.stat(filePath, (err, stat) => {
18 | if (!err && stat.isFile()) {
19 | response.writeHead(200);
20 | fs.createReadStream(filePath).pipe(response);
21 | } else if(!!stat.isDirectory()) {
22 | response.writeHead(200);
23 | fs.createReadStream(`${filePath}/index.html`).pipe(response);
24 | } else {
25 | console.log('404 ' + request.url);
26 | response.writeHead(404);
27 | response.end('404 Not Found');
28 | }
29 | });
30 | });
31 | server.listen(port, hostname, () => {
32 | console.log('The Server is running at port:4000');
33 | });
34 |
--------------------------------------------------------------------------------
/learn/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 文件服务器
7 |
8 |
9 |
10 | What we can do for you ?
11 |
12 |
13 |
--------------------------------------------------------------------------------
/learn/output.txt:
--------------------------------------------------------------------------------
1 | 使用Stream写入二进制数据...
2 | END.
--------------------------------------------------------------------------------
/learn/style.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | padding: 0px;
3 | margin: 0px;
4 | height: 100%;
5 | }
6 | body {
7 | font-size: 62.5%;
8 | color: #666;
9 | }
10 | div {
11 | width: 50vw;
12 | height: 50vw;
13 | margin: 0 auto;
14 | text-align: center;
15 | }
16 |
--------------------------------------------------------------------------------
/learn/test.txt:
--------------------------------------------------------------------------------
1 | 使用Stream写入二进制数据...
2 | END.
--------------------------------------------------------------------------------
/lib/database.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.insert = undefined;
7 |
8 | var _mongodb = require('mongodb');
9 |
10 | var _mongodb2 = _interopRequireDefault(_mongodb);
11 |
12 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13 |
14 | //初始化连接数据库,mongodb默认端口27017
15 | var server = new _mongodb2.default.Server('localhost', 27017, {
16 | auto_reconnect: true
17 | });
18 | //新建数据库名称learn
19 | //引入mongodb模块
20 | var db = new _mongodb2.default.Db('learn', server, {
21 | safe: true
22 | });
23 | console.log("database is running");
24 |
25 | var insert = exports.insert = function insert(fileName, filePath) {
26 | db.open(function (err, db) {
27 | if (!err) {
28 | /*
29 | 新建“表”pictures,这里仅为了演示node操作数据库的方式。因此只存储了文件名和文件路径。而且mongodb适合合保存JSON数据,不适合保存文件,可以考虑在JSON里面保存文件的路径名。如果实在需要把mongodb当成分布式文件系统,请用户GridFS
30 | */
31 | db.collection('pictures', function (err, collection) {
32 | collection.insert({
33 | filename: fileName,
34 | filepath: filePath
35 | }, function (err, docs) {
36 | console.log(docs);
37 | db.close();
38 | });
39 | });
40 | } else {
41 | console.log(err);
42 | }
43 | });
44 | };
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _server = require('./server');
4 |
5 | var _router = require('./router');
6 |
7 | var _requestHandlers = require('./requestHandlers');
8 |
9 | //创建handle对象
10 | var handle = {}; /*
11 | 本node应用实现了一个文件上传功能,涉及知识点有:服务端JavaScript、函数式编程、阻塞与非阻塞、回调、事件、内部和外部模块等等。可谓麻雀虽小,五脏俱全。
12 | */
13 | //引入server,router,requestHandlers模块
14 |
15 | handle['/'] = _requestHandlers.start;
16 | handle['/start'] = _requestHandlers.start;
17 | handle['/upload'] = _requestHandlers.upload;
18 | handle['/show'] = _requestHandlers.show;
19 | //进行函数传递
20 | (0, _server.firstStart)(_router.route, handle);
--------------------------------------------------------------------------------
/lib/requestHandlers.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.show = exports.upload = exports.start = undefined;
7 |
8 | var _querystring = require('querystring');
9 |
10 | var _querystring2 = _interopRequireDefault(_querystring);
11 |
12 | var _fs = require('fs');
13 |
14 | var _fs2 = _interopRequireDefault(_fs);
15 |
16 | var _formidable = require('formidable');
17 |
18 | var _formidable2 = _interopRequireDefault(_formidable);
19 |
20 | var _database = require('./database');
21 |
22 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23 |
24 | /*
25 | 引入Node.js 模块, child_process。之所以用它,是为了实现一个既简单又实用的非阻塞操作:exec()
26 | */
27 |
28 | // var exec = require('child_process').exec;
29 |
30 | /*
31 | querystring从字面上的意思就是查询字符串,是node的内置模块,一般是对http请求所带的数据进行解析。querystring模块只提供4个方法,在我看来,这4个方法是相对应的。
32 | 这4个方法分别是querystring.parse和querystring.stringify,querystring.escape和querystring.unescape。
33 | querystring.stringify()序列化;
34 | querystring.parse()反序列化;
35 | querystring.escape()编码;
36 | querystring.unescape()解码;
37 | fs模块可对本地文件进行操作,也是node内置模块,具体方法可看官方文档
38 | formidable模块是Felix Geisendörfer开发的。它对解析上传的文件数据做了很好的抽象。
39 | */
40 |
41 | var start = exports.start = function start(response, postData) {
42 | console.log('Start!!!');
43 | //尝试下列阻塞代码,感受下阻塞和非阻塞的区别
44 | // function sleep(time){
45 | // var startTime=new Date().getTime();
46 | // while(new Date().getTime()' + '' + '' + '' + '' + '' + '