Node.js 入门教程 (四):API

(一)URL网址解析

URI: 统一资源标识

URL:统一资源定位

网址就是一个URL,说明了要以那种协议来访问哪种资源,URI更加抽象,是一个字符串格式规范,URL是URI的子集

parse()

第二个参数设为true,可以看到query变成了一个对象

第三个参数设置前后的区别

 format()

resolve()

 

(二)querystring 参数处理

stringify()将对象序列化,第二个参数可以替换参数之间的连接值,第三个参数可替换key和value之间的连接值

parse()反序列化,第二三个参数和querystring一样

 

(三)http

http基础知识回顾

预备知识

nodejs的http模块:

支持更多特性

不缓冲请求和响应

处理流相关

一. 分析一个例子:

var http = require('http')
http
    .createServer(function(req, res){
        res.writeHead(200, {'Content-Type':'text/plain'})
        res.write('Hello Nodejs')
        res.end()
    })
    .listen(2015)

 

http.createServer(requestListener),返回了一个Server的实例,return new Server(requestListener)

如果requestListener存在,就会在当前实例上添加一个事件监听function addListener('request', requestListener),来监听request,当request事件发生,就会触发requestListener

那么什么时候request事件会发生呢?

在function parserOnIncoming(req,shouldKeepAlive)里面有一个emit('request',req,res),这里会触发request,这里的req,res就是回调函数接收的两个参数。

那什么时候生成的req和res呢?

req来自于new IncomingMessage(parser.socket)

在parserOnIncoming方法里面有一个res = new ServerResponse(req), ServerResponse是OutgoingMessage的一个子类

那什么时候会调用parserOnIncoming()呢?

parseOnIncoming 是在function connectionListener(socket)里面定义的,connectionListener又是在addListener('connection',connectionListener),也就是在connection事件的时候触发的

那connection事件又是什么时候触发的呢?

在net.js里面,在function onconnection()里面调用了emit('connection',socket),而onconnection又是在function _listen2()里面调用的,而_listen2正是在function listen()里面调用的

这就看出来了,listen最终会触发createServer的回调函数

 

二. get/request

在nodejs的http模块中,get就是对request的一个封装

request返回的是一个clientrequest实例,这个实例是一个可写的流,如果需要使用post请求上传一个文件,这个文件就会写入到clientrequest对象里面

http.request(options[, callback])  通过回调函数可以获取到远端服务器的响应数据,就是response

options可以是一个字符串,也可以是一个对象,如果是字符串,会被url.parse转化成对象

options参数:

host:server的域名或者ip地址

hostname:host别名

port:端口

localAddress:

socketPath:

method:指定http请求方法字符串,默认get

path:请求根路径,默认/

headers:包含请求头的对象

auth:用于基本认证,通常是user+password

agent:控制agent行为

keepAlive:保持资源池周围的套接字在未来可以被继续用于其他请求,默认false

keepAliveMsecs:

 

练习code:

var http = require('http')
var querystring = require('querystring')
var postData = querystring.stringify({
    'content':'赞赞赞赞赞',
    'cid':348
})
var options = {
    hostname: 'www.imooc.com',
    port:80,
    path: '/course/docomment',
    method:'POST',
    headers:{
        'Accept':'application/json, text/javascript, */*; q=0.01',
        'Accept-Encoding':'gzip, deflate',
        'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
        'Connection':'keep-alive',
        'Content-Length':postData.length,
        'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8',
        'Cookie':'imooc_uuid=60953301-958c-4cf7-a866-56e4d02fd502; imooc_isnew=2; imooc_isnew_ct=1509793366; Hm_lvt_f0cfcccd7b1393990c78efdeebff3968=1512455396,1512456206,1512545159,1512550843; IMCDNS=0; mc_channel=bdqdrmjt; mc_marking=f9afceb39ba1e46e460d601cb1580898; UM_distinctid=1602092f6e0151-07b07e399cf62f8-4c322e7d-1fa400-1602092f6e1e8; CNZZDATA1261110065=1792149044-1512373380-https%253A%252F%252Fwww.baidu.com%252F%7C1512373380; loginstate=1; last_login_username=freezer_lee%40yeah.net; apsid=E0MzdjNjhjYmFmYjIwMWQ4ZTlhNTU5MTM0MGFkZGEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjM4MDcwNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmcmVlemVyX2xlZUB5ZWFoLm5ldAAAAAAAAAAAAAAAADhmMTkzZThiMTlhMDc3NDdkYzY2Yzk2YWEzOTIyODk2wkMmWrBDJlo%3DYj; PHPSESSID=ud7oqkfi14r2b40uc2v6eb5d25; cvde=5a279b8336c6d-102; Hm_lpvt_f0cfcccd7b1393990c78efdeebff3968=1512566909',
        'Host':'www.imooc.com',
        'Referer':'http://www.imooc.com/comment/348',
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; …) Gecko/20100101 Firefox/57.0',
        'X-Requested-With':'XMLHttpRequest'
    }
}

var req = http.request(options, function(res){
    console.log('Status: ' + res.statusCode)
    console.log('headers: ' + JSON.stringify(res.headers))
    res.on('data',function(chunk){
        console.log(Buffer.isBuffer(chunk))
        console.log(typeof chunk)
    })
    res.on('end',function(){
        console.log('评论完毕')
    })
})
    req.on('error',function(e){
        console.log('error'+e.message)
    })
    req.write(postData)
    req.end()

运行结果:

解析:

我们在接收数据的时候,node是以流的形式来发送的,所以会触发data这个事件,所以可以为response的data事件注册一个函数,用来接收数据

当数据传输完毕,网络关闭连接的时候会触发end事件,同样可以添加回调函数

如果发生异常会抛出error事件

req.write把要提交的数据写入到请求体中,也就是postData中

req.end()

 

posted @ 2017-12-06 16:26  晓梅子酱  阅读(361)  评论(0编辑  收藏  举报