三.Node.js的常用内置模块
下面开始总结Node.js的内置模块了,如果你是入门学习的话,推荐按照本文顺序来学,学习思路会更清晰。如果你只是要查阅相关模块的用法,可以从目录索引导航到那一个模块。
1. http模块
http模块是 Node.js 网络的关键模块。可以使用以下代码引入:
const http = require('http')
该模块提供了一些属性、方法、以及类。我们要学习的就是一些常用的属性、方法、以及类的使用。
常用方法:
(1) http.createServer() :用于返回 http.Server 类的新实例。
用法:
const server = http.createServer((req, res) => { //使用此回调处理每个单独的请求。 })
(2) http.request() :用于发送 HTTP 请求到服务器,并创建 http.ClientRequest 类的实例。
(3) http.get() :类似于 http.request(),但会自动地设置 HTTP 方法为 GET,并自动地调用 req.end()。
常用属性:
(1) http.METHODS :此属性列出了所有支持的 HTTP 方法。像什么GET、POST、DELETE等等。
const http=require('http'); console.log(http.METHODS)
(2) http.STATUS_CODES
:此属性列出了所有的 HTTP请求的状态代码及其描述。
const http=require('http'); console.log(http.STATUS_CODES)
常用类:
HTTP 模块提供了5 个很常用的类,分别如下:
(1) http.Agent :Node.js 会创建 http.Agent 类的全局实例,以管理 HTTP 客户端连接的持久性和复用,这是 Node.js HTTP 网络的关键组成部分。该对象会确保对服务器的每个请求进行排队并且单个 socket 被复用,它还维护一个 socket 池。
(2) http.ClientRequest :当 http.request() 或 http.get() 被调用时,会创建 http.ClientRequest 对象。当响应被接收时,则会使用响应(http.IncomingMessage 实例作为参数)来调用 response 事件。返回的响应数据可以通过以下两种方式读取:
可以调用 response.read() 方法。
在 response 事件处理函数中,可以为 data 事件设置事件监听器,以便可以监听流入的数据。
(3) http.Server : 当使用 http.createServer() 创建新的服务器时,通常会实例化并返回此类。拥有服务器对象后,就可以访问其方法:
close() 停止服务器不再接受新的连接。
listen() 启动 HTTP 服务器并监听连接。
(4) http.ServerResponse :由 http.Server 创建,并作为第二个参数传给它触发的 request 事件。通常在代码中用作 res:
const server = http.createServer((req, res) => { //res 是一个 http.ServerResponse 对象。 })
这个类的以下这些方法用于与 HTTP 消息头进行交互:
在处理消息头之后,可以通过调用 response.writeHead()(该方法接受 statusCode 作为第一个参数,可选的状态消息和消息头对象)将它们发送给客户端。
若要在响应正文中发送数据给客户端,则使用 write()。 它会发送缓冲的数据到 HTTP 响应流。
如果消息头还未被发送,则使用 response.writeHead() 会先发送消息头,其中包含在请求中已被设置的状态码和消息,可以通过设置 statusCode 和 statusMessage 属性的值进行编辑:
response.statusCode = 500 response.statusMessage = '内部服务器错误'
(5) http.IncomingMessage
该类的对象可通过这两种方式创建:http.Server,当监听 request 事件时。http.ClientRequest,当监听 response 事件时。
它可以用来访问响应:
使用 statusCode 和 statusMessage 方法来访问状态。
使用 headers 方法或 rawHeaders 来访问消息头。
使用 method 方法来访问 HTTP 方法。
使用 httpVersion 方法来访问 HTTP 版本。
使用 url 方法来访问 URL。
使用 socket 方法来访问底层的 socket。
2. http模块简单案例实践
创建一个server.js,我们一点一点来用这个http模块:
const http=require('http') // 创建服务器 http.createServer((req,res)=>{ //接收浏览器传的参数,返回渲染的内容,都在这个回调函数里面来做 //req是接收的浏览器的参数,res是返回给浏览器渲染的内容。 }).listen(3000,()=>{ console.log("server start") }) /* listen()方法的第一个参数是端口号,第二个参数是一个回调函数,这个回调函数是服务器创建成功后执行的函数 */
命令行运行node server.js ,会看到server start打印在控制台了,并且光标在闪动,这表示服务创建成功,并监听了这个服务。现在浏览器访问http://localhost:3000/,浏览器还访问不到任何东西,因为我们没有返回任何数据。
我们可以在createServer()的回调里面调用res.write()对浏览器进行输出,res.write()可以调用多次,都会输出在浏览器上。但要注意,最后一定要掉用res.end()。不然浏览器会一直等,直到超时。
const http=require('http') // 创建服务器 http.createServer((req,res)=>{ //接收浏览器传的参数,返回渲染的内容,都在这个回调函数里面来做 //req是接收的浏览器的参数,res是返回给浏览器渲染的内容。 //可以用res.write()方法,向浏览器输出内容,并且可以写多个 res.write("hello world") res.write(" abc") //但要注意,最后一定要掉用res.end()。不然浏览器会一直等,直到超时。但end()后不能再进行其他操作了 res.end() }).listen(3000,()=>{ console.log("server start") }) /* listen()方法的第一个参数是端口号,第二个参数是一个回调函数,这个回调函数是服务器创建成功后执行的函数 */
我们改完代码记得重新运行node server.js
,重启服务,例如访问http://localhost:3000/。
res.end()
里面也可以传东西,也会在浏览器输出显示,如输出字符串。
const http=require('http') // 创建服务器 http.createServer((req,res)=>{ //接收浏览器传的参数,返回渲染的内容,都在这个回调函数里面来做 //req是接收的浏览器的参数,res是返回给浏览器渲染的内容。 //可以用res.write()方法,向浏览器输出内容,并且可以写多个 res.write("hello world") res.write(" abc") //但要注意,最后一定要掉用res.end()。不然浏览器会一直等,直到超时。但end()后不能再进行其他操作了 res.end("[1,2,3]") }).listen(3000,()=>{ console.log("server start") }) /* listen()方法的第一个参数是端口号,第二个参数是一个回调函数,这个回调函数是服务器创建成功后执行的函数 */
res.write()方法可以返回html标签,浏览器会渲染成html格式:
const http=require('http') // 创建服务器 http.createServer((req,res)=>{ //接收浏览器传的参数,返回渲染的内容,都在这个回调函数里面来做 //req是接收的浏览器的参数,res是返回给浏览器渲染的内容。 //res.write()方法可以返回html标签,浏览器会渲染成html格式 res.write(` <h1>hello world</h1> <h1>你好害恶细君</h1> `) //但要注意,最后一定要掉用res.end()。不然浏览器会一直等,直到超时。但end()后不能再进行其他操作了 res.end() }).listen(3000,()=>{ console.log("server start") }) /* listen()方法的第一个参数是端口号,第二个参数是一个回调函数,这个回调函数是服务器创建成功后执行的函数 */
虽然res.write()能在浏览器上生成html标签,但是却出现了一个问题,就是中文乱码。我们要通过使用res.writeHead()方法来给浏览器返回消息响应头
const http=require('http') // 创建服务器 http.createServer((req,res)=>{ //接收浏览器传的参数,返回渲染的内容,都在这个回调函数里面来做 //req是接收的浏览器的参数,res是返回给浏览器渲染的内容。 //使用res.writeHead()方法来给浏览器返回消息响应头 res.writeHead(200,{"Content-Type": "text/html; charset=utf-8"}) //res.write()方法可以返回html标签,浏览器会渲染成html格式 res.write(` <h1>hello world</h1> <h1>你好害恶细君</h1> `) //但要注意,最后一定要掉用res.end()。不然浏览器会一直等,直到超时。但end()后不能再进行其他操作了 res.end() }).listen(3000,()=>{ console.log("server start") }) /* listen()方法的第一个参数是端口号,第二个参数是一个回调函数,这个回调函数是服务器创建成功后执行的函数 */
此时,重启服务再访问浏览器时会就发现不会中文乱码了。
我们再来研究一下createServer()的回调里面的req,我们可以控制台打印一下这个req对象,会打印出非常多的东西,其中就有一个url属性,我们打印一下看看:
const http=require('http') // 创建服务器 http.createServer((req,res)=>{ //打印一下req.url console.log(req.url) res.writeHead(200,{"Content-Type": "text/html; charset=utf-8"}) res.end() }).listen(3000,()=>{ console.log("server start") })
我们运行后,在浏览器里面访问http://localhost:3000/haiexijun 等路径,会发现req.url
打印的就是这个路径:
到这里,我们就可以实现一个通过不同url路径来返回浏览器不同内容的功能:
const http=require('http') // 创建服务器 http.createServer((req,res)=>{ res.writeHead(renderStatus(req.url),{"Content-Type": "text/html; charset=utf-8"}) res.write(renderHTML(req.url)) res.end() }).listen(3000,()=>{ console.log("server start") }) function renderHTML(url){ switch (url){ case '/haiexijun': return ` <html> <h1>你好害恶细君</h1> </html> ` case '/world': return ` <html> <h1>你好世界</h1> </html> ` default : return ` <html> <h1>404 not found</h1> </html> ` } } function renderStatus(url){ var arr=["/haiexijun","/world"] return arr.includes(url)?200:404 }
上面案例中,只有访问 /haiexijun和/world 时才能访问到正确的页面,访问其他的路径时,就都会显示404 not found 的页面,并且状态码也会为404.
这里稍微体验一下就好,后面会学路由的模块和一些框架,http模块暂时就玩到这里。