[Node入门] => 读书笔记(三)
来源:互联网 发布:网络主播红人排行榜 编辑:程序博客网 时间:2024/06/01 14:36
相关笔记
- [Node入门] => 读书笔记(二)
- [Node入门] => 读书笔记(一)
学习内容
- Node入门
学习笔记
1. 一个完整的基于Node.js的Web应用
需求:
- 用户可以通过浏览器使用我们的应用。
- 当用户请求http://domain/start时,可以看到一个欢迎页面,页面上有一个文件上传的表单。
- 用户可以选择一个图片并提交表单,随后文件将被上传到http://domain/upload,该页面完成上传后会把图片显示在页面上。
实现:
- index.js 程序入口
- server.js 服务器模块,使用依赖注入,在index中将router功能和requestHandlers功能通过参数传入至服务器模块
- router.js 路由模块,通过handle对象,对传入的请求pathname进行处理。
- requestHandlers.js 请求处理模块,处理不同的请求URL,并在index中创建相应的handle对象进行映像,通过传递handle对象的方式来便捷处理。
代码:
/* index.js */const server = require('./server');const router = require('./router');const requestHandlers = require('./requestHandlers');var handle = {};handle['/'] = requestHandlers.start;handle['/start'] = requestHandlers.start;handle['/upload'] = requestHandlers.upload;handle['/show'] = requestHandlers.show;server.start(router.route, handle);
/* server.js */const http = require('http');const url = require('url');const port = 1337;const hostname = '127.0.0.1';function start(route, handle) { http.createServer((req, res) => { var pathname = url.parse(req.url).pathname; console.log(`Request for ${pathname} received.`); route(handle, pathname, req, res); }).listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}`); });}exports.start = start;
/* router.js */function route(handle, pathname, req, res) { console.log(`About to route a ${pathname}!`); if (typeof handle[pathname] === 'function') { handle[pathname](req, res); } else { console.log(`${pathname} was not found!`); res.writeHead(404, { 'Content-Type' : 'text/html' }); res.end('404 Not Found'); }}exports.route = route;
/* requestHandlers.js */const querystring = require('querystring');const fs = require('fs');const formidable = require('formidable');function start(req, res) { console.log('Request handler "start" was called'); var body = `<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Node入门-图片上传</title> </head> <body> <form action="/upload" enctype="multipart/form-data" method="post"> <input type="file" name="upload"> <input type="submit" value="上传"> </form> </body> </html> `; res.writeHead(200, { 'Content-Type' : 'text/html' }); res.end(body);}function upload(req, res) { console.log('Request handler "upload" was called'); var form = new formidable.IncomingForm(); form.uploadDir = './tmp'; // 解决cross-device link not permitted问题 form.parse(req, (err, fields, files) => { console.log('Parsing done'); fs.renameSync(files.upload.path, `./tmp/city1.jpg`); res.writeHead(200, { 'Content-Type' : 'text/html' }); res.end('received image:<br/><img src="/show">'); }); }function show(req, res) { console.log('Request handler "show" was called'); fs.readFile('./tmp/city1.jpg', 'binary', (err, file) => { if (err) { res.writeHead(500, { 'Content-Type' : 'text/html' }); res.end(err + '\n'); } else { res.writeHead(200, { 'Content-Type' : 'image/jpg' }); res.write(file, 'binary'); res.end(); } });}exports.start = start;exports.upload = upload;exports.show = show;
收获:
1. 了解了构建服务器基本的思路,通过路由将不同的请求分配给不同的请求处理程序进行处理。
2. 学会了如何搭建模块和不同模块之间的参数传递思路等等。
2. [NodeJs入门] 部分API中文翻译
1. http.createServer([requestListener])
返回类http.server一个新的实例对象。
参数requestListener是一个自动添加到’request’事件监听队列的函数。
2. server.listen(port[, hostname][, backlog][, callback])
开始在指定端口port和主机名hostname处接受连接。如果省略主机名hostname,当IPv6可用,服务器将会在任意的IPv6地址接受连接,否则在IPv4地址。端口值为零则会分配一个随机端口。
如果是要监听unix socket,则需要提供文件名而不是端口port和主机名hostname。
Backlog is the maximum length of the queue of pending connections. The actual length will be determined by your OS through sysctl settings such as tcp_max_syn_backlog and somaxconn on linux. 这个参数的缺省值为511(不是512)。
这个函数是异步的。最后一个参数callback将会作为监听器添加到’listening’事件。另见net.Server.listen(port)。
3. url.parse(urlStr[, parseQueryString][, slashesDenoteHost])
传入URL字符串并返回一个对象。
传入’true’作为第二个参数则使用’querystring’模块来解析查询字符串部分。If true then the query property will always be assigned an object, and the search property will always be a (possibly empty) string. If false then the query property will not be parsed or decoded. 默认值为’false’。
传入’true’作为第三个参数将视’//foo/bar’为’{ host: ‘foo’, pathname: ‘/bar’ }’ 而不是’{ pathname: ‘//foo/bar’ }’。 缺省值为’false’;
4. fs.renameSyne(oldPath, newPath)
同步函数’rename(2)’。返回’undefined’。
5. fs.readFile(file[, options], callback)
-> file: String|Integer 文件名或者文件描述符-> options: Object|String -> encoding: String|Null 缺省值为null -> flag: String 缺省值为’r’-> callback: Function
异步读取文件的全部内容。例如:
fs.readFile('/etc/passwd', (err, data) => { if (err) throw err; console.log(data);});
回调函数传入两个参数(err, data), 其中data为文件的内容。
如果没有指定编码方式,将会返回原生buffer。
如果options是一个字符串,那么它将特指编码方式,例如:
fs.readFile(‘/etc/passwd’, ‘utf8’, callback);
任何指定文件描述符都必须支持读取。
注意:指定的文件描述符将不会自动的关闭。
6. response.writeHead(statusCode[, statusMessage][, headers])
发送请求的响应头。状态码是一个三位的HTTP状态码,如404。最后一个参数headers,是响应头。能够可选的给出一个可读的状态信息作为第二个参数。
例如:
var body = 'hello world';response.writeHead(200, { 'Content-Length': body.length, 'Content-Type': 'text/plain' });
这个方法在当前请求中只能调用一次,并且必须在response.end()之前调用。
如果你在调用这个方法之前调用response.write()或者response.end(),隐式/可变的头部信息将会计算并自动调用此函数。
注意Content-Length是以字节而不是字符计算。上述例子能够执行是因为字符串’hello world’只包含单字节的字符。如果响应体包含多字节编码的字符,就该使用Buffer.byteLength()来确保该情况下的字节数。Node.js并不检查Content-Length和已传输body的长度是否一致。
尝试设置一个头部字段名或者值中包含无效字符将会抛出TypeError错误。
7. response.write(chunk[, encoding][, callback])
如果在该方法调用之前没有调用response.writeHead(),将会切换到隐式的header模式并更新隐式的headers。
这将发送响应体的数据块。这个方法可能会调用多次以连续的提供响应体的各部分内容。
数据块可以是string或者buffer。如果数据块是string,第二个参数指定如何将这个字符串编码编码成比特流,默认的编码格式为’utf8’。最后一个回调函数参数将会在清楚数据块之后调用。
注意:这是底层的HTPP报文,高级的多部分报文编码无法使用。
当第一次调用response.write(),将会发送缓存的头部信息和第一个报文给客户端。第二次调用response.write(),Node.js假设你将会分别发送数据流。这意味着响应缓存在第一个数据块中。
如果所有数据块刷新到内核缓存中将会返回true。如果所有或者部分数据还在用户内存队列中将会返回false。’drain’将会在缓冲释放时再次触发。
8. response.end([data][, encoding][, callback])
这个方法告知服务器所有的响应头响应体已经发送; 服务器确定该次信息已经发送完毕。这个方法response.end()必须在每一次响应中调用。
如果指定了数据,等同于调用response.write(data, encoding)之后再调用response.end(callback)。
如果指定了回调函数,它将会在响应流结束后调用。
完
- [Node入门] => 读书笔记(三)
- [Node入门] => 读书笔记(一)
- [Node入门] => 读书笔记(二)
- node入门(三)-- mysql
- 读书笔记之-node入门
- 《Node入门》读书笔记
- MySQL数据库入门--读书笔记(三)
- 从零开始node.js入门项目(三)基本构架
- Node.js开发入门(三)——HTTP文件服务器
- Node.js入门小记(三)Api之URL
- 算法竞赛入门经典读书笔记(三)7.2枚举排列
- Perl语言入门(第五版) 读书笔记(三)---哈希
- C#从入门到精通读书笔记 数组、哈希表(三)
- 算法竞赛入门经典读书笔记(三)7.2枚举排列
- Maven实战读书笔记之三(Maven使用入门)
- Java Web程序开发入门--读书笔记(三)
- Node.js-入门三--文件I/O
- Node入门(一)
- 分布式缓存系统_Memcached
- vim+python+OpenCV学习二 : 灰度图像 保存图像
- Ubuntu安装wine时停止在"正在设定ttf-mscorefonts-installer"解决方法
- HighCharts_数据值重叠问题
- 【慕课笔记】第二章 认识JAVA中的字符串 第5节 认识JAVA中stringBuilder类
- [Node入门] => 读书笔记(三)
- Java 序列化Serializable详解
- WebService梳理
- 使用HYPER-V搭建linux虚拟机
- C#基础之三大结构
- Solr配置扩展词/自定义词库(IK版)、如何做逻辑与逻辑或即AND OR查询
- BestCoder Round #73 (div.2)-Rikka with Graph(图的连通性)
- mpv播放器安装
- java排序算法之--归并排序