├── README.md
├── http-cache
├── cache_cache-control.js
├── cache_etag.js
├── cache_expires_pragma.js
├── cache_last-modified.js
├── index.html
├── index.js
└── picture.jpg
├── http
├── index.js
└── server.js
├── simple
└── index.js
├── step0
└── index.js
├── step1
├── readme.md
├── server-simple.js
├── server.js
└── static
│ ├── a.pdf
│ ├── css
│ └── a.css
│ ├── imgs
│ └── logo.png
│ ├── index.html
│ └── js
│ └── b.js
├── step2
├── server-simple.js
├── server.js
└── static
│ ├── css
│ └── a.css
│ ├── imgs
│ └── logo.png
│ ├── index.html
│ ├── js
│ └── b.js
│ └── user.tpl
├── step3
├── app.js
├── bin
│ └── www
└── lib
│ ├── express.js
│ └── express2.js
├── step4
├── app.js
├── bin
│ └── www
├── lib
│ ├── body-parser.js
│ └── express.js
└── static
│ ├── css
│ └── a.css
│ ├── imgs
│ └── logo.png
│ ├── index.html
│ └── js
│ └── b.js
└── step5
├── app.js
├── bin
└── www
├── lib
├── express.js
└── mime.js
├── package.json
├── static
├── css
│ └── a.css
├── imgs
│ └── logo.png
├── index.html
└── js
│ └── b.js
├── views
└── about.html
└── yarn.lock
/README.md:
--------------------------------------------------------------------------------
1 | # node-server
2 | nodejs 服务器
3 |
--------------------------------------------------------------------------------
/http-cache/cache_cache-control.js:
--------------------------------------------------------------------------------
1 | /*
2 | 缓存的第二种方案,浏览器把文件和附带信息保存起来。当再次需要a.jpg 时,如果是在300秒以内发起的请求则直接使用缓存(200, from memory cache),否则重新发起网络请求(200)。
3 |
4 |
5 | 请求报文
6 | - Cache-Control: max-age=10 //hi,(代理)服务器我想要
7 | - Cache-Control: no-cache // hi,(代理)服务器,不要给我缓存的东西,我要新鲜完整的内容
8 | - Cache-Control: no-store // hi,(代理)服务器, 这是机密请求,别缓存数据,给我最新的
9 | 响应报文
10 | - Cache-Control: max-age=10 //hi,浏览器,把这个文件信息保存起来。当再次需要它时,如果是在10秒以内发起的请求则直接使用缓存(200, from memory cache),否则重新发起网络请求找我要(200)
11 | - Cache-Control: no-cache // hi,浏览器(代理服务器),你可以缓存,但每次需要向我确认一下
12 | - Cache-Control: no-store // hi,浏览器(代理服务器),这是机密信息,别缓存
13 |
14 | 访问 http://localhost:8080/index.html */
15 |
16 | const http = require('http')
17 | const fs = require('fs')
18 | const path = require('path')
19 |
20 |
21 | http.createServer((req, res) => {
22 | let filePath = path.join(__dirname, req.url)
23 | fs.readFile(filePath, (err, data) => {
24 | if (err) {
25 | res.writeHead(404, 'not found')
26 | res.end('Oh, Not Found')
27 | } else {
28 |
29 | // example1
30 | //res.setHeader('Cache-Control', 'max-age=10')
31 |
32 |
33 | // example2
34 | //res.setHeader('Cache-Control', 'no-cache')
35 |
36 | // example3
37 | res.setHeader('Cache-Control', 'no-store')
38 |
39 |
40 | res.writeHead(200, 'OK')
41 | res.end(data)
42 | }
43 | })
44 | }).listen(8080)
45 | console.log('Visit http://localhost:8080' )
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/http-cache/cache_etag.js:
--------------------------------------------------------------------------------
1 |
2 | const http = require('http')
3 | const fs = require('fs')
4 | const path = require('path')
5 | const crypto = require('crypto')
6 |
7 |
8 |
9 |
10 | http.createServer((req, res) => {
11 | let filePath = path.join(__dirname, req.url)
12 | fs.readFile(filePath, (err, data) => {
13 | if (err) {
14 | res.writeHead(404, 'not found')
15 | res.end('Oh, Not Found')
16 | } else {
17 | // example1
18 | // let md5 = crypto.createHash('md5')
19 | // res.setHeader('Etag', md5.update(data).digest('base64'))
20 | // res.writeHead(200, 'OK')
21 | // res.end(data)
22 |
23 | // example2
24 | console.log(req.headers['if-none-match'])
25 | let oldEtag = req.headers['if-none-match']
26 | if(!oldEtag) {
27 | let md5 = crypto.createHash('md5')
28 | res.setHeader('Etag', md5.update(data).digest('base64'))
29 | res.writeHead(200, 'OK')
30 | res.end(data)
31 | } else {
32 | let newEtag = crypto.createHash('md5').update(data).digest('base64')
33 | if(oldEtag !== newEtag) {
34 | res.setHeader('Etag', newEtag)
35 | res.writeHead(200, 'OK')
36 | res.end(data)
37 | }else {
38 | res.writeHead(304)
39 | res.end()
40 | }
41 | }
42 |
43 |
44 |
45 | //example2
46 | // console.log(req.headers)
47 | // let mtime = Date.parse(fs.statSync(filePath).mtime)
48 | // if(!req.headers['if-modified-since']) {
49 | // res.setHeader('Last-Modified', new Date(mtime).toGMTString())
50 | // res.writeHead(200, 'OK')
51 | // res.end(data)
52 | // }else {
53 | // let oldMtime = Date.parse(req.headers['if-modified-since'])
54 | // if(mtime > oldMtime) {
55 | // res.setHeader('Last-Modified', new Date(mtime).toGMTString())
56 | // res.writeHead(200, 'OK')
57 | // res.end(data)
58 | // }else {
59 | // res.writeHead(304)
60 | // res.end()
61 | // }
62 | // }
63 |
64 | //example3
65 | // let mtime = Date.parse(fs.statSync(filePath).mtime)
66 | // //10秒内,浏览器直接从自己本地拿,10秒后找服务器要。如果没修改,告诉浏览器没修改就行,如果修改了,给浏览器最新的
67 | // res.setHeader('Cache-Control', 'max-age=10')
68 |
69 | // if(!req.headers['if-modified-since']) {
70 | // res.setHeader('Last-Modified', new Date(mtime).toGMTString())
71 | // res.writeHead(200, 'OK')
72 | // res.end(data)
73 | // }else {
74 | // let oldMtime = Date.parse(req.headers['if-modified-since'])
75 | // if(mtime > oldMtime) {
76 | // res.setHeader('Last-Modified', new Date(mtime).toGMTString())
77 | // res.writeHead(200, 'OK')
78 | // res.end(data)
79 | // }else {
80 | // res.writeHead(304)
81 | // res.end()
82 | // }
83 | // }
84 |
85 | }
86 | })
87 | }).listen(8080)
88 | console.log('Visit http://localhost:8080' )
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/http-cache/cache_expires_pragma.js:
--------------------------------------------------------------------------------
1 | /*
2 | 缓存的第一种方案,Http1.0时的产物,Expires字段表示过期截止日期,Pragma表示不用缓存
3 | 范例:
4 | Expires: Wed, 23 Jan 2019 07:33:51 GMT
5 | Pragma: no-cache
6 |
7 | 如果同时设置,Pragma的优先级高于Expires
8 |
9 | 访问 http://localhost:8080/picture.jpg */
10 |
11 | const http = require('http')
12 | const fs = require('fs')
13 | const path = require('path')
14 |
15 |
16 | http.createServer((req, res) => {
17 | let filePath = path.join(__dirname, req.url)
18 | fs.readFile(filePath, (err, data) => {
19 | if (err) {
20 | res.writeHead(404, 'not found')
21 | res.end('Oh, Not Found')
22 | } else {
23 |
24 | // example1
25 | res.setHeader('Expires', 'Wed, 23 Jan 2019 07:40:51 GMT')
26 |
27 |
28 | // example2
29 | //res.setHeader('Pragma', 'no-cache')
30 |
31 | // example3
32 | //res.setHeader('Expires', 'Wed, 23 Jan 2019 07:40:51 GMT')
33 | //res.setHeader('Pragma', 'no-cache')
34 |
35 | // example4
36 | let date = new Date(Date.now() + 1000*5).toGMTString()
37 | res.setHeader('Expires', date)
38 |
39 | res.writeHead(200, 'OK')
40 | res.end(data)
41 | }
42 | })
43 | }).listen(8080)
44 | console.log('Visit http://localhost:8080' )
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/http-cache/cache_last-modified.js:
--------------------------------------------------------------------------------
1 |
2 | const http = require('http')
3 | const fs = require('fs')
4 | const path = require('path')
5 |
6 |
7 | http.createServer((req, res) => {
8 | let filePath = path.join(__dirname, req.url)
9 | fs.readFile(filePath, (err, data) => {
10 | if (err) {
11 | res.writeHead(404, 'not found')
12 | res.end('Oh, Not Found')
13 | } else {
14 | // example1
15 | // let stat = fs.statSync(filePath)
16 | // console.log(stat.mtime)
17 | // let modifyDate = new Date(Date.parse(stat.mtime)).toGMTString()
18 | // console.log(modifyDate)
19 | // res.setHeader('Last-Modified', modifyDate)
20 | // res.writeHead(200, 'OK')
21 | // res.end(data)
22 |
23 |
24 | //example2
25 | // console.log(req.headers)
26 | // let mtime = Date.parse(fs.statSync(filePath).mtime)
27 | // if(!req.headers['if-modified-since']) {
28 | // res.setHeader('Last-Modified', new Date(mtime).toGMTString())
29 | // res.writeHead(200, 'OK')
30 | // res.end(data)
31 | // }else {
32 | // let oldMtime = Date.parse(req.headers['if-modified-since'])
33 | // if(mtime > oldMtime) {
34 | // res.setHeader('Last-Modified', new Date(mtime).toGMTString())
35 | // res.writeHead(200, 'OK')
36 | // res.end(data)
37 | // }else {
38 | // res.writeHead(304)
39 | // res.end()
40 | // }
41 | // }
42 |
43 | //example3
44 | let mtime = Date.parse(fs.statSync(filePath).mtime)
45 | //10秒内,浏览器直接从自己本地拿,10秒后找服务器要。如果没修改,告诉浏览器没修改就行,如果修改了,给浏览器最新的
46 | res.setHeader('Cache-Control', 'max-age=10')
47 |
48 | if(!req.headers['if-modified-since']) {
49 | res.setHeader('Last-Modified', new Date(mtime).toGMTString())
50 | res.writeHead(200, 'OK')
51 | res.end(data)
52 | }else {
53 | let oldMtime = Date.parse(req.headers['if-modified-since'])
54 | if(mtime > oldMtime) {
55 | res.setHeader('Last-Modified', new Date(mtime).toGMTString())
56 | res.writeHead(200, 'OK')
57 | res.end(data)
58 | }else {
59 | res.writeHead(304)
60 | res.end()
61 | }
62 | }
63 |
64 | }
65 | })
66 | }).listen(8080)
67 | console.log('Visit http://localhost:8080' )
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/http-cache/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 缓存控制
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/http-cache/index.js:
--------------------------------------------------------------------------------
1 | /* 一个最简单的静态服务器 */
2 | /* 访问 http://localhost:8080/picture.jpg */
3 |
4 | const http = require('http')
5 | const fs = require('fs')
6 | const path = require('path')
7 |
8 |
9 | http.createServer((req, res) => {
10 | fs.readFile(path.join(__dirname, req.url), (err, data) => {
11 | if (err) {
12 | res.writeHead(404, 'not found')
13 | res.end('Oh, Not Found')
14 | } else {
15 | res.writeHead(200, 'OK')
16 | res.end(data)
17 | }
18 | })
19 | }).listen(8080)
20 | console.log('Visit http://localhost:8080' )
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/http-cache/picture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jirengu/node-server/a43fea14cdfa1f6e5ba0ad4128df1bde5d2e79ff/http-cache/picture.jpg
--------------------------------------------------------------------------------
/http/index.js:
--------------------------------------------------------------------------------
1 | let http = require('http')
2 |
3 | let server = http.createServer(function(req, res) {
4 | console.log(req.headers)
5 | console.log(req.url)
6 | res.statusCode = 500
7 | // res.statusMessage = 'Jirengu'
8 | // res.setHeader('location', 'https://jirengu.com')
9 | res.setHeader('Content-Type', 'text/plain; charset=utf-8')
10 | res.end('hello
')
11 | })
12 | server.listen(3000)
--------------------------------------------------------------------------------
/http/server.js:
--------------------------------------------------------------------------------
1 | let http = require('http')
2 |
3 | http.createServer((req, res) => {
4 | console.log(req.rawHeaders)
5 | console.log(req.headers)
6 | // res.statusCode = 204
7 | // res.statusMessage = 'Very Good'
8 | res.setHeader('Content-Type', 'text/html')
9 | res.setHeader('By', 'jirengu')
10 | //res.writeHead(301, 'redirect forever haha', { 'Content-Type': 'text/plain', location: 'https://baidu.com' });
11 | //res.writeHead(302, { 'Content-Type': 'text/plain', location: 'https://baidu.com' });
12 | res.writeHead(302, { 'Content-Type': 'text/plain', location: 'https://baidu.com' })
13 | res.end('ok')
14 | }).listen(8080)
--------------------------------------------------------------------------------
/simple/index.js:
--------------------------------------------------------------------------------
1 | var http = require('http')
2 | var path = require('path')
3 | var fs = require('fs')
4 | var url = require('url')
5 |
6 | var router = {
7 | '/getData': function(req, res){
8 | var pathObj = url.parse(req.url, true)
9 |
10 | var page = pathObj.query.page
11 | var result
12 |
13 | if(page == 1){
14 | result = [1,2,3]
15 | }
16 | if(page == 2){
17 | result = [4,5,6]
18 | }
19 |
20 | res.write(JSON.stringify(result))
21 | res.end()
22 | },
23 | '/hello': function(req, res){
24 | res.end('hello world')
25 | }
26 | }
27 |
28 |
29 | var server = http.createServer(function(req, res){
30 | var staticPath = path.join(__dirname, 'www')
31 | var pathObj = url.parse(req.url, true)
32 | var filePath = path.join(staticPath, pathObj.pathname)
33 | try{
34 | var fileContent = fs.readFileSync(filePath,'binary')
35 | res.write(fileContent, 'binary')
36 | res.end()
37 | }catch(e){
38 |
39 | if(router[pathObj.pathname]){
40 | router[pathObj.pathname](req, res)
41 | }else{
42 | res.writeHead(404, 'not found')
43 | res.end('not found')
44 | }
45 | }
46 |
47 | })
48 |
49 | server.listen(8080)
50 |
--------------------------------------------------------------------------------
/step0/index.js:
--------------------------------------------------------------------------------
1 | var http = require('http')
2 |
3 | // var server = http.createServer(function(req, res){
4 | // console.log('jiengu')
5 | // res.setHeader("Content-Type","text/html; charset=utf-8")
6 | // res.write(' 饥人谷
')
7 | // res.end()
8 | // })
9 | // server.listen(9000)
10 |
11 |
12 | var server = http.createServer(function(request, response){
13 | setTimeout(function(){
14 |
15 |
16 | response.setHeader('Content-Type','text/html; charset=utf-8')
17 | response.writeHead(404, 'Not Found')
18 | response.write('')
19 | response.write('')
20 | response.write('你好
')
21 | response.write('')
22 | response.write('')
23 |
24 | response.end()
25 | },2000);
26 | })
27 |
28 | console.log('open http://localhost:8080')
29 | server.listen(8080)
--------------------------------------------------------------------------------
/step1/readme.md:
--------------------------------------------------------------------------------
1 | ###
2 | http://www.open-open.com/solution/view/1321344823593
--------------------------------------------------------------------------------
/step1/server-simple.js:
--------------------------------------------------------------------------------
1 | var http = require('http')
2 | var fs = require('fs')
3 |
4 |
5 | var server = http.createServer(function(req, res){
6 | try{
7 | var fileContent = fs.readFileSync(__dirname + '/static' + req.url)
8 | res.write(fileContent)
9 | }catch(e){
10 | res.writeHead(404, 'not found')
11 | }
12 | res.end()
13 | })
14 |
15 | server.listen(8080)
16 | console.log('visit http://localhost:8080' )
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/step1/server.js:
--------------------------------------------------------------------------------
1 | var http = require('http')
2 | var path = require('path')
3 | var fs = require('fs')
4 | var url = require('url')
5 |
6 |
7 | function staticRoot(staticPath, req, res){
8 | console.log(staticPath)
9 |
10 | console.log(req.url)
11 | var pathObj = url.parse(req.url, true)
12 | console.log(pathObj)
13 |
14 |
15 | if(pathObj.pathname === '/'){
16 | pathObj.pathname += 'index.html'
17 | }
18 |
19 |
20 |
21 |
22 | var filePath = path.join(staticPath, pathObj.pathname)
23 |
24 | // var fileContent = fs.readFileSync(filePath,'binary')
25 | // res.write(fileContent, 'binary')
26 | // res.end()
27 |
28 |
29 | fs.readFile(filePath, 'binary', function(err, fileContent){
30 | if(err){
31 | console.log('404')
32 | res.writeHead(404, 'not found')
33 | res.end('404 Not Found
')
34 | }else{
35 | console.log('ok')
36 | res.writeHead(200, 'OK')
37 | res.write(fileContent, 'binary')
38 | res.end()
39 | }
40 | })
41 |
42 |
43 | }
44 |
45 | console.log(path.join(__dirname, 'static'))
46 |
47 | var server = http.createServer(function(req, res){
48 | staticRoot(path.join(__dirname, 'static'), req, res)
49 | })
50 |
51 | server.listen(8080)
52 | console.log('visit http://localhost:8080' )
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/step1/static/a.pdf:
--------------------------------------------------------------------------------
1 | hello
--------------------------------------------------------------------------------
/step1/static/css/a.css:
--------------------------------------------------------------------------------
1 | h1{
2 | color: red;
3 | }
--------------------------------------------------------------------------------
/step1/static/imgs/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jirengu/node-server/a43fea14cdfa1f6e5ba0ad4128df1bde5d2e79ff/step1/static/imgs/logo.png
--------------------------------------------------------------------------------
/step1/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | hello
6 |
7 |
8 |
9 | hello world
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/step1/static/js/b.js:
--------------------------------------------------------------------------------
1 | alert('hello')
--------------------------------------------------------------------------------
/step2/server-simple.js:
--------------------------------------------------------------------------------
1 | var http = require('http')
2 | var fs = require('fs')
3 | var url = require('url')
4 |
5 |
6 |
7 | http.createServer(function(req, res){
8 |
9 | var pathObj = url.parse(req.url, true)
10 | console.log(pathObj)
11 |
12 | switch (pathObj.pathname) {
13 | case '/getWeather':
14 | var ret
15 | if(pathObj.query.city == 'beijing'){
16 | ret = {
17 | city: 'beijing',
18 | weather: '晴天'
19 | }
20 | }else{
21 | ret = {
22 | city: pathObj.query.city,
23 | weather: '不知道'
24 | }
25 | }
26 | res.end(JSON.stringify(ret))
27 | break;
28 | case '/user/123':
29 |
30 | res.end( fs.readFileSync(__dirname + '/static/user.tpl' ))
31 | break;
32 | default:
33 | res.end( fs.readFileSync(__dirname + '/static' + pathObj.pathname) )
34 | }
35 | }).listen(8080)
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/step2/server.js:
--------------------------------------------------------------------------------
1 | var http = require('http')
2 | var path = require('path')
3 | var fs = require('fs')
4 | var url = require('url')
5 |
6 | var routes = {
7 | '/a': function(req, res){
8 | res.end(JSON.stringify(req.query))
9 | },
10 |
11 | '/b': function(req, res){
12 | res.end('match /b')
13 | },
14 |
15 | '/a/c': function(req, res){
16 | res.end('match /a/c')
17 | },
18 |
19 | '/search': function(req, res){
20 | res.end('username='+req.body.username+',password='+req.body.password)
21 |
22 | }
23 |
24 | }
25 |
26 |
27 | var server = http.createServer(function(req, res){
28 | routePath(req, res)
29 | })
30 |
31 | server.listen(8080)
32 | console.log('visit http://localhost:8080' )
33 |
34 |
35 | function routePath(req, res){
36 | var pathObj = url.parse(req.url, true)
37 |
38 | var handleFn = routes[pathObj.pathname]
39 | if(handleFn){
40 | req.query = pathObj.query
41 |
42 | //参考 https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/
43 | // post json 解析
44 | var body = ''
45 | req.on('data', function(chunk){
46 | body += chunk
47 | }).on('end', function(){
48 | req.body = parseBody(body)
49 | handleFn(req, res)
50 | })
51 |
52 | }else {
53 | staticRoot(path.resolve(__dirname, 'static'), req, res)
54 | }
55 | }
56 |
57 | function staticRoot(staticPath, req, res){
58 | var pathObj = url.parse(req.url, true)
59 | var filePath = path.join(staticPath, pathObj.pathname)
60 | fs.readFile(filePath,'binary', function(err, content){
61 | if(err){
62 | res.writeHead('404', 'haha Not Found')
63 | return res.end()
64 | }
65 |
66 | res.writeHead(200, 'Ok')
67 | res.write(content, 'binary')
68 | res.end()
69 | })
70 |
71 | }
72 |
73 | function parseBody(body){
74 | console.log(body)
75 | var obj = {}
76 | body.split('&').forEach(function(str){
77 | obj[str.split('=')[0]] = str.split('=')[1]
78 | })
79 | return obj
80 | }
81 |
82 |
83 |
--------------------------------------------------------------------------------
/step2/static/css/a.css:
--------------------------------------------------------------------------------
1 | h1{
2 | color: red;
3 | }
--------------------------------------------------------------------------------
/step2/static/imgs/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jirengu/node-server/a43fea14cdfa1f6e5ba0ad4128df1bde5d2e79ff/step2/static/imgs/logo.png
--------------------------------------------------------------------------------
/step2/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | hello
6 |
7 |
8 |
9 | hello world
10 |
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/step2/static/js/b.js:
--------------------------------------------------------------------------------
1 |
2 | var xhr = new XMLHttpRequest()
3 | xhr.open('GET', '/getWeather?city=hangzhou', true)
4 | xhr.send()
5 | xhr.onload = function(){
6 | console.log(JSON.parse(xhr.responseText))
7 | }
--------------------------------------------------------------------------------
/step2/static/user.tpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | user
6 |
7 |
8 | I am user page
9 |
10 |
--------------------------------------------------------------------------------
/step3/app.js:
--------------------------------------------------------------------------------
1 | var express = require('./lib/express')
2 | var path = require('path')
3 |
4 |
5 |
6 | var app = express()
7 |
8 |
9 | //app.use(express.static(path.join(__dirname, 'public')))
10 |
11 |
12 | app.use(function(req, res, next) {
13 | console.log('middleware 1')
14 | next()
15 | })
16 |
17 | app.use(function(req, res, next) {
18 | console.log('middleware 12')
19 | next()
20 | })
21 |
22 |
23 | app.use('/hello', function(req, res){
24 | console.log('/hello..')
25 | res.send('hello world')
26 | })
27 |
28 | app.use('/getWeather', function(req, res){
29 | res.send({url:'/getWeather', city: req.query.city})
30 | })
31 |
32 | app.use(function(req, res){
33 | res.send(404, 'haha Not Found')
34 | })
35 |
36 |
37 | module.exports = app
38 |
--------------------------------------------------------------------------------
/step3/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 |
4 | var app = require('../app')
5 | var http = require('http')
6 | console.log(app)
7 |
8 | http.createServer(app).listen(8080)
9 | console.log('open http://localhost:8080')
10 |
11 |
--------------------------------------------------------------------------------
/step3/lib/express.js:
--------------------------------------------------------------------------------
1 | var url = require('url')
2 |
3 |
4 | function express() {
5 |
6 | var tasks = []
7 |
8 | var app = function(req, res){
9 | makeQuery(req)
10 | makeResponse(res)
11 |
12 | var i = 0
13 |
14 | function next() {
15 | var task = tasks[i++]
16 | if(!task) {
17 | return
18 | }
19 |
20 | //如果是普通的中间件 或者 是路由匹配上的中间件
21 | if(task.routePath === null || url.parse(req.url, true).pathname === task.routePath){
22 | task.middleWare(req, res, next)
23 | }else{
24 | //如果说路由未匹配上的中间件,直接下一个
25 | next()
26 | }
27 | }
28 |
29 | next()
30 | }
31 |
32 | app.use = function(routePath, middleWare){
33 | if(typeof routePath === 'function') {
34 | middleWare = routePath
35 | routePath = null
36 | }
37 |
38 | tasks.push({
39 | routePath: routePath,
40 | middleWare: middleWare
41 | })
42 | }
43 |
44 |
45 | return app
46 |
47 | }
48 |
49 | express.static = function(path){
50 |
51 | return function(req, res){
52 |
53 | }
54 | }
55 |
56 | module.exports = express
57 |
58 |
59 | function makeQuery(req){
60 | var pathObj = url.parse(req.url, true)
61 | req.query = pathObj.query
62 | }
63 |
64 | function makeResponse(res){
65 | res.send = function(toSend){
66 | if(typeof toSend === 'string'){
67 | res.end(toSend)
68 | }
69 | if(typeof toSend === 'object'){
70 | res.end(JSON.stringify(toSend))
71 | }
72 | if(typeof toSend === 'number'){
73 | res.writeHead(toSend, arguments[1])
74 | res.end()
75 | }
76 | }
77 | }
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/step3/lib/express2.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | function express() {
4 | // body...
5 |
6 | var app = function(){
7 |
8 | }
9 |
10 | app.use = function(fn){
11 |
12 | }
13 |
14 | return app
15 | }
16 |
17 | module.exports = express
--------------------------------------------------------------------------------
/step4/app.js:
--------------------------------------------------------------------------------
1 | var express = require('./lib/express')
2 | var path = require('path')
3 | var bodyParser = require('./lib/body-parser')
4 |
5 |
6 | var app = express()
7 |
8 |
9 | app.use(bodyParser)
10 | app.use(express.static(path.join(__dirname, 'static')))
11 |
12 |
13 | app.use(function(req, res, next) {
14 | console.log('middleware 1')
15 | next()
16 | })
17 |
18 | app.use(function(req, res, next) {
19 | console.log('middleware 12')
20 | next()
21 | })
22 |
23 |
24 | app.use('/hello', function(req, res){
25 | console.log('/hello..')
26 | res.send('hello world')
27 | })
28 |
29 | app.use('/getWeather', function(req, res){
30 | res.send({url:'/getWeather', city: req.query.city})
31 | })
32 |
33 | app.use('/search', function(req, res){
34 | res.send(req.body)
35 | })
36 |
37 | app.use(function(req, res){
38 | res.send(404, 'haha Not Found')
39 | })
40 |
41 |
42 | module.exports = app
43 |
--------------------------------------------------------------------------------
/step4/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 |
4 | var app = require('../app')
5 | var http = require('http')
6 | console.log(app)
7 |
8 | http.createServer(app).listen(8080)
9 | console.log('open http://localhost:8080')
10 |
11 |
--------------------------------------------------------------------------------
/step4/lib/body-parser.js:
--------------------------------------------------------------------------------
1 |
2 | function bodyParser(req, res, next){
3 | var body = ''
4 | req.on('data', function(chunk){
5 | body += chunk
6 | }).on('end', function(){
7 | req.body = parseBody(body)
8 | next()
9 | })
10 | }
11 |
12 | function parseBody(body){
13 | var obj = {}
14 | body.split('&').forEach(function(str){
15 | obj[str.split('=')[0]] = str.split('=')[1]
16 | })
17 | return obj
18 | }
19 |
20 | module.exports = bodyParser
--------------------------------------------------------------------------------
/step4/lib/express.js:
--------------------------------------------------------------------------------
1 | var url = require('url')
2 | var fs = require('fs')
3 | var path = require('path')
4 |
5 |
6 | function express() {
7 |
8 | var tasks = []
9 |
10 | var app = function(req, res){
11 |
12 | makeQuery(req)
13 | makeResponse(res)
14 | console.log(tasks)
15 |
16 | var i = 0
17 |
18 | function next() {
19 | var task = tasks[i++]
20 | if(!task) {
21 | return
22 | }
23 | if(task.routePath === null || url.parse(req.url, true).pathname === task.routePath){
24 | task.middleWare(req, res, next)
25 | }else{
26 | next()
27 | }
28 | }
29 |
30 | next()
31 | }
32 |
33 | app.use = function(routePath, middleWare){
34 | if(typeof routePath === 'function') {
35 | middleWare = routePath
36 | routePath = null
37 | }
38 |
39 | tasks.push({
40 | routePath: routePath,
41 | middleWare: middleWare
42 | })
43 | }
44 |
45 |
46 | return app
47 |
48 | }
49 |
50 | express.static = function(staticPath){
51 |
52 | return function(req, res, next){
53 | var pathObj = url.parse(req.url, true)
54 | var filePath = path.resolve(staticPath, pathObj.pathname.substr(1))
55 | console.log(filePath)
56 | fs.readFile(filePath,'binary', function(err, content){
57 | if(err){
58 | next()
59 | }else {
60 | res.writeHead(200, 'Ok')
61 | res.write(content, 'binary')
62 | res.end()
63 | }
64 | })
65 | }
66 | }
67 |
68 | module.exports = express
69 |
70 |
71 | function makeQuery(req){
72 | var pathObj = url.parse(req.url, true)
73 | req.query = pathObj.query
74 | }
75 |
76 | function makeResponse(res){
77 | res.send = function(toSend){
78 | if(typeof toSend === 'string'){
79 | res.end(toSend)
80 | }
81 | if(typeof toSend === 'object'){
82 | res.end(JSON.stringify(toSend))
83 | }
84 | if(typeof toSend === 'number'){
85 | res.writeHead(toSend, arguments[1])
86 | res.end()
87 | }
88 | }
89 | }
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/step4/static/css/a.css:
--------------------------------------------------------------------------------
1 | h1{
2 | color: red;
3 | }
--------------------------------------------------------------------------------
/step4/static/imgs/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jirengu/node-server/a43fea14cdfa1f6e5ba0ad4128df1bde5d2e79ff/step4/static/imgs/logo.png
--------------------------------------------------------------------------------
/step4/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | hello
6 |
7 |
8 |
9 | hello world
10 |
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/step4/static/js/b.js:
--------------------------------------------------------------------------------
1 | alert('hello')
--------------------------------------------------------------------------------
/step5/app.js:
--------------------------------------------------------------------------------
1 | var express = require('./lib/express')
2 | var path = require('path')
3 | var bodyParser = require('body-parser')
4 | var urlencodedParser = bodyParser.urlencoded({ extended: false })
5 | var mimeType = require('./lib/mime')
6 |
7 |
8 | var app = express()
9 |
10 |
11 | app.use(urlencodedParser)
12 | app.use(mimeType)
13 | app.use(express.static(path.join(__dirname, 'static')))
14 | app.set('views', path.join(__dirname, 'views'))
15 |
16 |
17 | app.use(function(req, res, next) {
18 | console.log('middleware 1')
19 | next()
20 | })
21 |
22 | app.use(function(req, res, next) {
23 | console.log('middleware 12')
24 | next()
25 | })
26 |
27 |
28 | app.use('/hello', function(req, res){
29 | console.log('/hello..')
30 | res.send('hello world')
31 | })
32 |
33 | app.use('/getWeather', function(req, res){
34 | res.send({url:'/getWeather', city: req.query.city})
35 | })
36 |
37 | app.use('/search', function(req, res){
38 | res.send(req.body)
39 | })
40 |
41 | app.use('/about', function(req, res){
42 | res.render('about.html', {
43 | title: '饥人谷直播14班开班了',
44 | teacher: '若愚',
45 | date: '7月中旬',
46 | intro: 'http://jirengu.com'
47 | })
48 | })
49 |
50 | app.use(function(req, res){
51 | res.send(404, 'haha Not Found')
52 | })
53 |
54 |
55 | module.exports = app
56 |
--------------------------------------------------------------------------------
/step5/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 |
4 | var app = require('../app')
5 | var http = require('http')
6 | console.log(app)
7 |
8 | http.createServer(app).listen(8080)
9 | console.log('open http://localhost:8080')
10 |
11 |
--------------------------------------------------------------------------------
/step5/lib/express.js:
--------------------------------------------------------------------------------
1 | var url = require('url')
2 | var fs = require('fs')
3 | var path = require('path')
4 | var ejs = require('ejs')
5 |
6 |
7 | function express() {
8 |
9 | var tasks = []
10 |
11 | var app = function(req, res){
12 |
13 | addQuery(req, res)
14 | addSend(req, res)
15 | addRender(req, res, app)
16 |
17 | var i = 0
18 |
19 | function next() {
20 | var task = tasks[i++]
21 | if(!task) {
22 | return
23 | }
24 | if(task.routePath === null || url.parse(req.url, true).pathname === task.routePath){
25 | task.middleWare(req, res, next)
26 | }else{
27 | next()
28 | }
29 | }
30 |
31 | next()
32 | }
33 |
34 | app.use = function(routePath, middleWare){
35 | if(typeof routePath === 'function') {
36 | middleWare = routePath
37 | routePath = null
38 | }
39 |
40 | tasks.push({
41 | routePath: routePath,
42 | middleWare: middleWare
43 | })
44 | }
45 |
46 | app.data = {}
47 |
48 | app.set = function(key, value){
49 | app.data[key] = value
50 | }
51 |
52 | app.get = function(key){
53 | return app.data[key]
54 | }
55 |
56 | return app
57 |
58 | }
59 |
60 | express.static = function(staticPath){
61 |
62 | return function(req, res, next){
63 | var pathObj = url.parse(req.url, true)
64 | var filePath = path.resolve(staticPath, pathObj.pathname.substr(1))
65 | console.log(filePath)
66 | fs.readFile(filePath,'binary', function(err, content){
67 | if(err){
68 | next()
69 | }else {
70 | res.writeHead(200, 'Ok')
71 | res.write(content, 'binary')
72 | res.end()
73 | }
74 | })
75 | }
76 | }
77 |
78 | module.exports = express
79 |
80 |
81 | function addQuery(req, res){
82 | var pathObj = url.parse(req.url, true)
83 | req.query = pathObj.query
84 | }
85 |
86 | function addSend(req, res){
87 | res.send = function(toSend){
88 | if(typeof toSend === 'string'){
89 | res.end(toSend)
90 | }
91 | if(typeof toSend === 'object'){
92 | res.end(JSON.stringify(toSend))
93 | }
94 | if(typeof toSend === 'number'){
95 | res.writeHead(toSend, arguments[1])
96 | res.end()
97 | }
98 | }
99 | }
100 |
101 | function addRender(req, res, app){
102 |
103 | res.render = function(tplPath, data) {
104 |
105 | var fullpath = path.join(app.get('views'), tplPath)
106 | ejs.renderFile(fullpath, data, {}, function(err, str){
107 | if(err){
108 | res.writeHead(503, 'System error')
109 | res.end()
110 | }else {
111 | res.setHeader('content-type', 'text/html')
112 | res.writeHead(200, 'Ok')
113 | res.write(str)
114 | res.end()
115 | }
116 | })
117 |
118 | }
119 | }
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/step5/lib/mime.js:
--------------------------------------------------------------------------------
1 |
2 | var url = require('url')
3 | var mime = require('mime-types')
4 |
5 | function Mime(req, res, next){
6 | var pathObj = url.parse(req.url, true)
7 | var mimeType = mime.lookup(pathObj.pathname)
8 | console.log(mimeType)
9 |
10 | res.setHeader('content-type', mimeType)
11 | next()
12 | }
13 |
14 | module.exports = Mime
--------------------------------------------------------------------------------
/step5/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "step5",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "dependencies": {
7 | "body-parser": "^1.17.2",
8 | "ejs": "^2.5.6",
9 | "mime-types": "^2.1.15"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/step5/static/css/a.css:
--------------------------------------------------------------------------------
1 | h1{
2 | color: red;
3 | }
--------------------------------------------------------------------------------
/step5/static/imgs/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jirengu/node-server/a43fea14cdfa1f6e5ba0ad4128df1bde5d2e79ff/step5/static/imgs/logo.png
--------------------------------------------------------------------------------
/step5/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | hello
6 |
7 |
8 |
9 | hello world
10 |
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/step5/static/js/b.js:
--------------------------------------------------------------------------------
1 | alert('hello')
--------------------------------------------------------------------------------
/step5/views/about.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | about
6 |
7 |
8 |
9 | <%= title %>
10 |
11 | - 老师:
12 | - <%= teacher %>
13 | - 开班日期:
14 | - <%= date %>
15 | - 课程大纲:
16 | - 点击查看
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/step5/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | body-parser@^1.17.2:
6 | version "1.17.2"
7 | resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.17.2.tgz#f8892abc8f9e627d42aedafbca66bf5ab99104ee"
8 | dependencies:
9 | bytes "2.4.0"
10 | content-type "~1.0.2"
11 | debug "2.6.7"
12 | depd "~1.1.0"
13 | http-errors "~1.6.1"
14 | iconv-lite "0.4.15"
15 | on-finished "~2.3.0"
16 | qs "6.4.0"
17 | raw-body "~2.2.0"
18 | type-is "~1.6.15"
19 |
20 | bytes@2.4.0:
21 | version "2.4.0"
22 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.4.0.tgz#7d97196f9d5baf7f6935e25985549edd2a6c2339"
23 |
24 | content-type@~1.0.2:
25 | version "1.0.2"
26 | resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed"
27 |
28 | debug@2.6.7:
29 | version "2.6.7"
30 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.7.tgz#92bad1f6d05bbb6bba22cca88bcd0ec894c2861e"
31 | dependencies:
32 | ms "2.0.0"
33 |
34 | depd@1.1.0, depd@~1.1.0:
35 | version "1.1.0"
36 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3"
37 |
38 | ee-first@1.1.1:
39 | version "1.1.1"
40 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
41 |
42 | ejs@^2.5.6:
43 | version "2.5.6"
44 | resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.6.tgz#479636bfa3fe3b1debd52087f0acb204b4f19c88"
45 |
46 | http-errors@~1.6.1:
47 | version "1.6.1"
48 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.1.tgz#5f8b8ed98aca545656bf572997387f904a722257"
49 | dependencies:
50 | depd "1.1.0"
51 | inherits "2.0.3"
52 | setprototypeof "1.0.3"
53 | statuses ">= 1.3.1 < 2"
54 |
55 | iconv-lite@0.4.15:
56 | version "0.4.15"
57 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb"
58 |
59 | inherits@2.0.3:
60 | version "2.0.3"
61 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
62 |
63 | media-typer@0.3.0:
64 | version "0.3.0"
65 | resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
66 |
67 | mime-db@~1.27.0:
68 | version "1.27.0"
69 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1"
70 |
71 | mime-types@^2.1.15, mime-types@~2.1.15:
72 | version "2.1.15"
73 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed"
74 | dependencies:
75 | mime-db "~1.27.0"
76 |
77 | ms@2.0.0:
78 | version "2.0.0"
79 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
80 |
81 | on-finished@~2.3.0:
82 | version "2.3.0"
83 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
84 | dependencies:
85 | ee-first "1.1.1"
86 |
87 | qs@6.4.0:
88 | version "6.4.0"
89 | resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
90 |
91 | raw-body@~2.2.0:
92 | version "2.2.0"
93 | resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.2.0.tgz#994976cf6a5096a41162840492f0bdc5d6e7fb96"
94 | dependencies:
95 | bytes "2.4.0"
96 | iconv-lite "0.4.15"
97 | unpipe "1.0.0"
98 |
99 | setprototypeof@1.0.3:
100 | version "1.0.3"
101 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04"
102 |
103 | "statuses@>= 1.3.1 < 2":
104 | version "1.3.1"
105 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"
106 |
107 | type-is@~1.6.15:
108 | version "1.6.15"
109 | resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410"
110 | dependencies:
111 | media-typer "0.3.0"
112 | mime-types "~2.1.15"
113 |
114 | unpipe@1.0.0:
115 | version "1.0.0"
116 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
117 |
--------------------------------------------------------------------------------