阅读前言NodeJS中用来创建服务的模块是http核心模块。本文介绍了使用http模块搭建HTTP服务器和客户端的方法,以及该模块的基本API。HTTP服务器1.创建HTTP服务器在NodeJS中,创建HTTP服务器可以类比使用net模块创建TCP服务器。创建服务器有两种方法。方法一:consthttp=require("http");constserver=http.createServer(function(req,res){//......});服务器.listen(3000);方法二:consthttp=require("http");constserver=http.createServer();server.on("request",function(req,res){//......});server.听(3000);createServer和request事件的回调函数中有两个参数,req(request)和res(response),基于socket,这两个对象都是Duplex类型的可读可写流。http模块是基于net模块实现的,所以net模块原有的事件在http中依然存在。consthttp=require("http");constserver=http.createServer();//网络模块事件server.on("connection",function(socket){console.log("connectionsuccessful");});服务器.listen(3000);2、获取请求信息在请求对象req中,有请求方法、请求url(包括参数,即查询字符串)、当前HTTP协议版本和请求头等信息。consthttp=require("http");constserver=http.createServer();server.on("request",function(req,res){console.log(req.method);//获取请求方法console.log(req.url);//获取请求路径(包括查询字符串)console.log(req.httpVersion);//获取HTTP协议版本console.log(req.headers);//获取请求header(object)//获取请求体的内容letarr=[];req.on("data",function(data){arr.push(data);});req.on("end",function(){console.log(Buffer.concat(arr).toString());});});server.listen(3000,function(){console.log("serverstart3000");});通过req的相应属性获取请求行和请求头信息,通过流操作获取请求体中的内容。url中有很多有用的参数,我们处理起来会比较麻烦,可以通过NodeJS的核心模块url来解析。consturl=require("url");letstr="http://user:pass@www.pandashen.com:8080/src/index.html?a=1&b=2#hash";//解析方法帮助我们解析url路径letobj=url.parse(str,true);console.log(obj);//{//protocol:'http:',//slashes:true,//auth:'user:pas',//host:'www.pandashen.com:8080',//port:'8080',//hostname:'www.pandashen.com',//hash:'#hash',//search:'?a=1&b=2',//query:'{a:'1',b:'2'}',//pathname:'/src/index.html'//path:'/src/index.html?a=1&b=2',//href:'http://user:pass@www.pandashen.com:8080/src/index.html?a=1&b=2#hash'}解析路径返回的几个对象中经常使用的属性:host:主机(域名+端口号);主机名:主机名;query:请求参数(查询字符串或参数对象);pathname:资源路径(返回不同的资源)。我们使用url的parse方法来帮我们解析请求路径。真实服务器传入的第一个参数是req.url。当不传第二个参数时,query会被解析成a=1&b=2的形式,第二个参数传true,query属性的querystring会被解析成object的形式。在url模块中,将查询字符串a=1&b=2转换为对象{a:'1',b:'2'}的实现实际上是使用正则替换实现的。模拟查询字符串转换对象的核心逻辑:letstr="a=1&b=2&c=3";letobj={};str.replace(/([^=&]+)=([^=&]+)/g,function(){obj[arguments[1]]=arguments[2];});安慰。日志(对象);//{a:'1',b:'2',c:'3'}在上述代码的replace方法的回调函数中,参数集的第一项为匹配的字符串,第二项为第一组的值,第三项是第二组的值,依此类推。倒数第二项是分组匹配的索引,最后一项是原始字符串。3、设置响应信息我们可以通过req获取请求信息,自然也可以通过res设置响应信息返回给客户端。consthttp=require("http");constserver=http.createServer();server.on("request",function(req,res){//设置响应头(以往用法),不能多次调用,Res.writeHead(200,{"Content-Type":"text",a:"helloworld"});//设置响应头(当前使用,常用),可以多次调用,每次设置一个响应头res.setHeader("Content-Type","text");//设置状态码,如果不设置,默认为200res.statusCode=200;//不发送Date(日期)响应headerres.sendDate=false;//返回内容res.write("helloworld");//不会关闭连接res.end("helloworld");//返回内容后关闭连接});server.listen(3000,function(){console.log("serverstart3000");});返回给客户端的信息主要分为两部分,分别是响应头和返回给浏览器的内容。如果没有设置响应头,默认会设置响应头Content-Length和Date,代表当前返回给客户端的内容长度和日期。返回给浏览器的内容可以通过res的write方法和end方法发送。write方法不会断开连接(一般在response后需要断开client),end方法会断开连接,end方法存在参数设置时,内部会调用write返回参数内容给client,并且连接将断开。HTTP客户端可以通过net模块中的net.createConnection创建客户端,向服务器端发送请求。它还可以在http模块中创建一个客户端,向http服务器发送请求。//Client:client.jsconsthttp=require("http");//发送请求的配置letconfig={host:"localhost",port:3000,method:"get",headers:{a:1}};//创建客户端letclient=http.request(config,function(res){//接收服务器返回的数据letarr=[];res.on("data",function(data){arr.push(data);});res.on("end",function(){console.log(Buffer.concat(arr).toString());});});//发送请求client.end();通过http模块中的request方法创建客户端。该方法第一个参数是发送请求的配置,包括请求地址、端口号、请求方法和请求头等,第二个参数是回调函数,响应后执行,回调的参数function是服务端的响应对象res,创建的客户端通过end方法发送请求与服务端通信。使用NodeJS实现的“爬虫”其实可以通过http模块创建的客户端来实现。客户端帮我们向我们要抓取数据的地址发送请求,得到响应数据进行分析。同时使用HTTP客户端和服务端我们使用自己创建的客户端访问自己的服务端,体验请求响应的过程,即使用上面的client.js作为客户端,启动server.js然后启动client.js看看效果。//Server:server.jsconsthttp=require("http");http.createServer(function(req,res){console.log("Therequestcame");//获取客户端请求信息console.log(req.method);console.log(req.headers);//返回数据res.write("helloworld");}).listen(3000,function(){console.log("serverstart3000");});简单爬虫我们结合http模块创建的服务端和客户端,实现一个简单版的“爬虫”,抓取百度新闻页面所有li标签中的文章标题。//简单爬虫:crawl.jsconsthttp=require("http");//创建服务器constserver=http.createServer();//监听请求server.on("request",function(req,res){letclient=http.request({host:"news.baidu.com",method:"get",port:80},function(r){//接收百度新闻返回的数据letarr=[];r.on("data",function(data){arr.push(data);});r.on("end",function(){//处理数据letresult=Buffer.concat(arr).toString();letmatches=result.match(/
