你是程序猿对吗?会写Bug的那种?
Node.js标准库提供了 http 模块,是Node.js中非常重要的一个核心模块。通过http模块,你可以使用其http.createServer方法创建一个http服务器
,也可以使用其http.request方法创建一个http客户端。
文章目录
第一部分: http服务端
1.1 HTTP是什么?
HTTP是一个用来传送数据的应用层协议,在其底层使用TCP传输协议。HTTP是互联网数据通信的基础,要响应客户端请求(如:浏览器访问),首先要布署HTTP服务器。
1.2 HTTP之URL
URL: (Uniform / Universal Resource Locator,常缩写为URL)统一资源定位符,统一资源定位符的标准格式如下:
协议类型://服务器地址(必要时需加上端口号)/路径/文件名
http1-url-structure.png
1.3 http之请求报文
一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成;
2012072810301161.png
举例子:
201411187986714.png
请求报文中关键的字段:
User-Agent:产生请求的浏览器类型;
Accept:客户端可识别的响应内容类型列表;星号 “ * ” 用于按范围将类型分组,用 “ */* ” 指示可接受全部类型,用“ type/* ”指示可接受 type 类型的所有子类型;
Accept-Language:客户端可接受的自然语言;
Accept-Encoding:客户端可接受的编码压缩格式;
Accept-Charset:可接受的应答的字符集;
Host:请求的主机名,允许多个域名同处一个IP 地址,即虚拟主机;
connection:连接方式(close 或 keepalive);
Cookie:存储于客户端扩展字段,向同一域名的服务端发送属于该域的cookie;
1.4 HTTP响应报文
HTTP 响应报文由状态行、响应头部、空行 和 响应包体 4 个部分组成
201446213766964.jpg
状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。
1xx:指示信息--表示请求已接收,继续处理。
2xx:成功--表示请求已被成功接收、理解、接受。
3xx:重定向--要完成请求必须进行更进一步的操作。
4xx:客户端错误--请求有语法错误或请求无法实现。
5xx:服务器端错误--服务器未能实现合法的请求。
常见的状态码:
200 OK:客户端请求成功。
400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
403 Forbidden:服务器收到请求,但是拒绝提供服务。
404 Not Found:请求资源不存在,举个例子:输入了错误的URL。
500 Internal Server Error:服务器发生不可预期的错误。
503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。
第二部分 http服务器端
1.1 http.server遵循了node.js的时间模块的规则, 有触发和相应事件;http.Server对象是一个EventEmitter;
创建: http.createServer方法会返回一个http.Server对象实例,requestListener可选参数传入时,将做为http.Server对象'request'事件的监听器。
http.Server对象提供的事件方法有:
1. request: function (request, response) { }每次请求都会触发该方法;
2. connection:当TCP连接建立时,该事件被触发,提供一个参数socket,是net.Socket的实例;
3. close: 当此服务器关闭时触发;
等等..
1.2 http.Server中的方法
2.2.1 server.listen(port[, hostname][, backlog][, callback])
在指定的主机名(hostname)和端口(port)开始接收连接,
1.2.2 server.listen(path, [callback])
监听某个
2. http.ServerResponse服务器响应对象
http.ServerResponse是一个由http.Server创建的对象, ,在触发'request'事件后,做事件回调函数的第二个参数传递给回调函数.
2.1 response.writeHead(statusCode[, statusMessage][, headers])
向客户端请求发送一个响应头。statusCode状态码是 3 位数字,如:404。可通过statusMessage设置状态消息。最后一个参数headers是响应头。这个方法只能在当前请求中使用一次,并且必须在response.end()之前调用。
var body = 'hello world';
response.writeHead(200, {
'Content-Length': body.length,
'Content-Type': 'text/plain' });
2.2 response.setHeader(name, value)
为默认或者已存在的头设置一条单独的头内容。如果这个头已经存在于 将被送出的头中,将会覆盖原来的内容。如果我想设置更多的头, 就使用一个相同名字的字符串数组
2.3 response.write(chunk, [encoding])
向响应流发送一个数据块。这个方法可能被调用多次,以提供响应体内容。
2.4 response.end([data], [encoding])
当所有的响应报头和报文被发送完成时这个方法将信号发送给服务器,服务器会认为这个消息完成了。 每次响应完成之后必须调用该方法。
第三部分 http客户端
http模块提供了两个创建HTTP客户端的方法http.request和http.get,以向HTTP服务器发起请求。http.get是http.request快捷方法,该方法仅支持GET方式的请求。
一个 IncomingMessage对象是由 http.Server或http.ClientRequest创建的,并作为第一参数分别传递给'request'和'response' 事件。它也可以被用来访问应答的状态,头文件和数据。
var http = require('http');
http.createServer(function (req, res) {
var content = "";
req.on('data', function (chunk) {
content += chunk;
});
req.on('end', function () {
res.writeHead(200, {"Content-Type": "text/plain"});
res.write("You've sent: " + content);
res.end();
});
}).listen(3000);
data事件会在数据接收过程中,每收到一段数据就触发一次,接收到的数据被传入回调函数。end事件则是在所有数据接收完成后触发。
3.1 http.request(options[, callback])
request方法的options参数,可以是一个对象,也可以是一个字符串。如果是字符串,就表示这是一个URL,Node内部就会自动调用url.parse(),处理这个参数。
options对象可以设置如下属性:
host:HTTP请求所发往的域名或者IP地址,默认是localhost。
hostname:该属性会被url.parse()解析,优先级高于host。
port:远程服务器的端口,默认是80。
localAddress:本地网络接口。
socketPath:Unix网络套接字,格式为host:port或者socketPath。
method:指定HTTP请求的方法,格式为字符串,默认为GET。
path:指定HTTP请求的路径,默认为根路径(/)。可以在这个属性里面,指定查询字符串,比如/index.html?page=12。如果这个属性里面包含非法字符(比如空格),就会抛出一个错误。
headers:一个对象,包含了HTTP请求的头信息。
auth:一个代表HTTP基本认证的字符串user:password。
agent:控制缓存行为,如果HTTP请求使用了agent,则HTTP请求默认为Connection: keep-alive,它的可能值如下:
undefined(默认):对当前host和port,使用全局Agent。
Agent:一个对象,会传入agent属性。
false:不缓存连接,默认HTTP请求为Connection: close。
keepAlive:一个布尔值,表示是否保留socket供未来其他请求使用,默认等于false。
keepAliveMsecs:一个整数,当使用KeepAlive的时候,设置多久发送一个TCP KeepAlive包,使得连接不要被关闭。默认等于1000,只有keepAlive设为true的时候,该设置才有意义。
var http = require('http');
http.createServer(function(req, res){
//仅对从http.Server获得到的请求(request)有效.
console.log(req.url);
//请求/响应 头对象.
console.log(req.headers);
//服务器的HTTP版本。
console.log(req.httpVersion);
//接收到的原始请求/响应头字段列表。
console.log(req.rawHeaders);
//仅对从http.Server获得到的请求(request)有效.比如‘GET’、‘DELETE’。
console.log(req.method);
}).listen(3000, '127.0.0.1');
第四部分 实例
4.1 创建服务器, 实现GET方法
var http = require('http');
//创建一个服务器, 回调函数的参数为响应, 和请求
http.createServer(function(request, response){
//response.writeHead方法用来写入HTTP回应的头信息;
response.writeHead(200, {'Content-Type': 'text/plain'});
//指定HTTP回应的内容。
//response.write('hello world');
//response.end方法用来写入HTTP回应的具体内容,以及回应完成后关闭本次对话。
response.end('hello world');
//监听端口号和主机名
}).listen(3000, '127.0.0.1');
console.log('127.0.0.1:3000');
4.2 加载HTML文件
var http = require('http');
var fs = require('fs');
http.createServer(function(req, res){
//读取HTML文件
fs.readFile('./2index.html', 'utf-8',function(err, data){
if(err) throw err;
//为默认或者已存在的头设置一条单独的头内容。
res.setHeader("Content-Type","text/html;charset='utf-8'");
//响应的数据
res.end(data);
});
}).listen(3000, '127.0.0.1');
4.3 创建服务器, 实现POST方法
一个简单的post请求:
var http = require('http');
var fs = require('fs');
http.createServer(function(req, res) {
//fs模块创建流文件, 名称为post.txt
var file = fs.createWriteStream('post.txt');
////管子 pipe自动调用了data,end等事件 writeStream/readStream
req.pipe(file);
// 当有数据流时,写入数据
req.on('data', function(postData){
console.log(postData);
});
req.on('end', function(){
res.end('end');
});
}).listen(3000);
注意:本文归作者所有,未经作者允许,不得转载