├── 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 |
12 | 13 | 14 | 15 |
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 |
12 | 13 | 14 | 15 |
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 |
12 | 13 | 14 | 15 |
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 | --------------------------------------------------------------------------------