5. Node.js Http模块

2.4 Http模块

2.4.1创建Http服务端
js 复制代码
//1.导入http模块
let http=require('http')

//2.创建服务对象
let server=http.createServer((request,response)=>{
    console.log(request.method)        //获取请求方式
    console.log(request.url)           //获取请求url(路径和参数部份)
    console.log(request.httpVersion)   //获取请求http版本号
    console.log(request.headers)       //获取请求头
    //设置响应头,如果返回的内容中有中文,需要设置一下以下响应头,否则会出现乱码
    response.setHeader("content-type","text/html;charset=utf-8")
    //响应结束后返回的内容
    response.end('你好HTTP Server')
})
//启动服务,并配置监听端口
server.listen(9000,()=>{
    console.log('服务已启动')
})

执行这个js文件后,就可以通过浏览器访问本机的9000端口,并得到了响应

2.4.2获取request中的请求体
js 复制代码
//1.导入http模块
let http=require('http')

//2.创建服务对象
let server=http.createServer((request,response)=>{
    let body=''
    request.on('data',chunk=>{
        //持续读取request中的请求体
        body += chunk
    })
    request.on('end',()=>{
        //读取request中的请求体结束后,执行的代码
        console.log(typeof(body))
        console.log(body)
        response.end('Hello Http server')
    })
})
//启动服务,并配置监听端口
server.listen(9000,()=>{
    console.log('服务已启动')
})

使用postman发送post请求

输出:

js 复制代码
服务已启动
string
{

    "name": "muyi",
    "gender": 1,
    "birth": "1983-03-13",
    "grade": 3

}
2.4.3获取url中的路径和参数

用户访问的url:

http://localhost:9000/test/?arg1=1&arg2=2
js 复制代码
//获取url中的路径和参数(方法1)
//1.导入http模块
let http=require('http')
//2.导入url模块
let url=require('url')


//3.创建服务对象
let server=http.createServer((request,response)=>{
    //解析request.url,后面不如不加true,则获取到的参数是字符串,加上true后获取到的参数是一个字典,方便提取数据
    res=url.parse(request.url,true)
    console.log(res)
    console.log('path:',res.pathname)          //获取路径:/test/
    console.log('args1:',res.query.args1)      //获取参数1:1
    console.log('args2:',res.query.args2)      //获取参数2:2
    
    response.end('Hello Http Server')
})
//4.启动服务,并配置监听端口
server.listen(9000,()=>{
    console.log('服务已启动')
})

输出:

js 复制代码
Url {
  protocol: null,
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: null,
  search: '?arg1=1&arg2=2',
  query: [Object: null prototype] { arg1: '1', arg2: '2' },
  pathname: '/test/',
  path: '/test/?arg1=1&arg2=2',
  href: '/test/?arg1=1&arg2=2'
}
path: /test/
args1: 1
args2: 2
js 复制代码
//获取url中的路径和参数(方法2)
//1.导入http模块
let http=require('http')

//2.创建服务对象
let server=http.createServer((request,response)=>{
    let url=new URL(request.url,'http://127.0.0.1')
    console.log(url)
    console.log('path:',url.pathname)                       //获取路径:/test/
    console.log('arg1:',url.searchParams.get('arg1'))       //获取参数1:1
    console.log('arg2:',url.searchParams.get('arg2'))       //获取参数2:2
    response.end('Hello Http Server')
})
//3.启动服务,并配置监听端口
server.listen(9000,()=>{
    console.log('服务已启动')
})

输出:

js 复制代码
URL {
  href: 'http://127.0.0.1/test/?arg1=1&arg2=2',
  origin: 'http://127.0.0.1',
  protocol: 'http:',
  username: '',
  password: '',
  host: '127.0.0.1',
  hostname: '127.0.0.1',
  port: '',
  pathname: '/test/',
  search: '?arg1=1&arg2=2',
  searchParams: URLSearchParams { 'arg1' => '1', 'arg2' => '2' },
  hash: ''
}
path: /test/
arg1: 1
arg2: 2
2.4.4 HTTP请求练习

需求:

​ 当用户的请求路径是GET且请求路径为/login或/login/时,返回login;

​ 当用户的请求路径是GET且请求路径为/reg或/reg/时,返回login;

​ 上面两种情况都不符合时,返回'Not Found'

js 复制代码
//1.导入http模块
let http=require('http')

//2.创建服务对象
let server=http.createServer((request,response)=>{
    let url=new URL(request.url,'http://127.0.0.1')   
    if (request.method=='GET' && (url.pathname=='/login/' || url.pathname=='/login')){
        //判断请求类型是不是为GET,且路径是否为'/login/'或'/login'
        response.end('login')
    }else if(request.method=='GET' && (url.pathname=='/reg/' || url.pathname=='/reg')){
        //判断请求类型是不是为GET,且路径是否为'/reg/'或'/reg'
        response.end('reg')

    }else{
        
        response.end('Not Found')
    }

    
})
//3.启动服务,并配置监听端口
server.listen(9000,()=>{
    console.log('服务已启动')
})
2.4.5设置HTTP响应报文
js 复制代码
//1.导入http模块
let http=require('http')

//2.创建服务对象
let server=http.createServer((request,response)=>{

    response.statusCode = 201                     //设置响应code
    response.statusMessage = 'success'            //设置响应信息
 
    response.setHeader('content-type','text/html;charset=utf-8')        //设置响应头
    response.setHeader('Server','node.js')                              //设置自定义响应头
    response.setHeader('myHeader',[1,2,3])                              //设置多个同名响应头

    response.write('I love sally1')                                     //设置响应体
    response.write('I love sally2')                                     //设置响应体
    response.end('success')                                             //end方法只能有一个

    
})
//3.启动服务,并配置监听端口
server.listen(9000,()=>{
    console.log('服务已启动')
})

浏览器中查看响应报文


2.4.6将HTML文件做为响应体

1)创建一个HTML文件

html 复制代码
<!-- template.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>node.js学习</h1>
</body>
</html>

2)node.js

js 复制代码
//1.导入http模块
let http=require('http')
var fs=require('fs')

//2.创建服务对象
let server=http.createServer((request,response)=>{

    let html=fs.readFileSync('./template.html')                         //读取html文件中的内容 
    response.end(html)                                                  //将读取到的html文件中的内容传递给用户

    
})
//3.启动服务,并配置监听端口
server.listen(9000,()=>{
    console.log('服务已启动')
})
2.4.7设置资源类型(mime类型)

媒体类型(通常称为Multipurpose Internet Mail Extensions或MIME类型)是一种标准,用来表示文档、文件或字节流的性质和格式。

mime 类型结构:[type]/[subType]
例如: text/html,text/css,text/jpeg,image/png,application/json

HTTP服务可以设置响应头Content-Type来表明响应体的MIME类型,浏览器会根据该类型决定如何处理资源。

常见的文件对应的mime类型

html:'text/html',
css:'text/css',
js:'text/js',
png:'image/png',
jpg:'image/jpeg',
gif:'image/gif',
mp4:'video/mp4',
mp3:'audio/mpeg',
json:'application/json'

对于未知的资源类型,可以选择类型,浏览器在遇到该类型的响应时,会对响应体内容进行独立存储,也就是我们常见的下载效果。

2.4.8搭建静态资源服务并设置响应头
js 复制代码
//1.导入http模块
let http=require('http')
var fs=require('fs')
var path =require('path')
var root='g:\\py_project\\nodejs_study\\page'                           //指定项目根目录
var index='index.html'                                                  //默认访问的文件

//定义所有资源类型(mime类型)
var mimes={
    html:'text/html',
    css:'text/css',
    js:'text/js',
    png:'image/png',
    jpg:'image/jpeg',
    gif:'image/gif',
    mp4:'video/mp4',
    mp3:'audio/mpeg',
    json:'application/json'
}
//2.创建服务对象
let server=http.createServer((request,response)=>{
      if (request.method != 'GET'){
        //如果请求类型不是GET,则返回错误信息
        response.statusCode = 404;
        response.end('405 Method Not Allowed')
        return
    }
    //获取请求路径
    let filePath=request.url
    if (filePath=='/'){
        //如果请求的路径是/,则让它等于默认访问的文件 
        filePath='/'+ index  
    }
    //获取请求中的文件名扩展名
    let ext=path.extname(filePath).substring(1,)
    //获取请求访问的资源类型(响应头content-type的值)
    let type=mimes[ext]
    
    fs.readFile(root+filePath,(err,data)=>{
        //读取请求中要访问的文件内容,并设置响应头
        //如请求的是/index.html,就去读取g:\\py_project\\nodejs_study\\page\\index.html
        //如果请求的是/img/img.png,就去读取g:\\py_project\\nodejs_study\\page\\img\\img.png文件
        if (err){            
            response.setHeader('content-type','text/html;charset=utf-8')
            console.log(err);
            switch(err.code){
                //根据不同的err.code返回给用户不同的错误信息
                case 'ENOENT':
                    response.statusCode = 404; 
                    response.end('404 Page Not Found');
                case 'EPERM':
                    response.statusCode = 403; 
                    response.end('403 Operation not permitted')
                default:
                    response.statusCode = 400;
                    response.end('400 Unknown error')
            return

            }
           
        }else{            
            if (type){
                 response.setHeader('content-type',type + ';charset=utf-8')
            }else{
                //如果请求访问的资源类型不存在,则将content-type设为'application/octet-stream'
                //浏览器在遇到该类型的响应时,会对响应体内容进行独立存储,也就是我们常见的下载效果。
                response.setHeader('content-type','application/octet-stream')
            }
            //将读取到的文件内容传递给用户
            response.end(data) 
        }
    })                         
    
                                                   

    
})
//3.启动服务,并配置监听端口
server.listen(9000,()=>{
    console.log('服务已启动')
})
2.4.9常见错误码
Common system errors
This is a list of system errors commonly-encountered when writing a Node.js program. For a comprehensive list, see the errno(3) man page.

EACCES (Permission denied): An attempt was made to access a file in a way forbidden by its file access permissions.

EADDRINUSE (Address already in use): An attempt to bind a server (net, http, or https) to a local address failed due to another server on the local system already occupying that address.

ECONNREFUSED (Connection refused): No connection could be made because the target machine actively refused it. This usually results from trying to connect to a service that is inactive on the foreign host.

ECONNRESET (Connection reset by peer): A connection was forcibly closed by a peer. This normally results from a loss of the connection on the remote socket due to a timeout or reboot. Commonly encountered via the http and net modules.

EEXIST (File exists): An existing file was the target of an operation that required that the target not exist.

EISDIR (Is a directory): An operation expected a file, but the given pathname was a directory.

EMFILE (Too many open files in system): Maximum number of file descriptors allowable on the system has been reached, and requests for another descriptor cannot be fulfilled until at least one has been closed. This is encountered when opening many files at once in parallel, especially on systems (in particular, macOS) where there is a low file descriptor limit for processes. To remedy a low limit, run ulimit -n 2048 in the same shell that will run the Node.js process.

ENOENT (No such file or directory): Commonly raised by fs operations to indicate that a component of the specified pathname does not exist. No entity (file or directory) could be found by the given path.

ENOTDIR (Not a directory): A component of the given pathname existed, but was not a directory as expected. Commonly raised by fs.readdir.

ENOTEMPTY (Directory not empty): A directory with entries was the target of an operation that requires an empty directory, usually fs.unlink.

ENOTFOUND (DNS lookup failed): Indicates a DNS failure of either EAI_NODATA or EAI_NONAME. This is not a standard POSIX error.

EPERM (Operation not permitted): An attempt was made to perform an operation that requires elevated privileges.

EPIPE (Broken pipe): A write on a pipe, socket, or FIFO for which there is no process to read the data. Commonly encountered at the net and http layers, indicative that the remote side of the stream being written to has been closed.

ETIMEDOUT (Operation timed out): A connect or send request failed because the connected party did not properly respond after a period of time. Usually encountered by http or net. Often a sign that a socket.end() was not properly called.
相关推荐
桃酥4035 分钟前
day05|计算机网络重难点之 HTTPS和HTTP的区别、HTTPS的工作原理(HTTPS建立连接的过程)、TCP和UDP的区别
计算机网络·http·https·udp·tcp
桃酥40331 分钟前
day04|计算机网络重难点之HTTP/1.0和HTTP/1.1的区别、HTTP/2.0与HTTP/1.1的区别、介绍HTTP/3.0
网络协议·计算机网络·http
长安初雪2 小时前
浅析HTTP协议
网络·网络协议·http
懒惰树人2 小时前
渗透测试-百日筑基—SQL注入篇&时间注入&绕过&HTTP数据编码&绕过—下
网络·sql·安全·web安全·http·oracle
掌控安全EDU2 小时前
安全研究 | 不同编程语言中 IP 地址分类的不一致性
网络协议·tcp/ip·安全·xss
bjzhang7512 小时前
Depcheck——专门用于检测 JavaScript 和 Node.js 项目中未使用依赖项的工具
javascript·node.js·depcheck
bossface13 小时前
申请https证书
服务器·网络协议·https·ssl
hanniuniu1314 小时前
动态威胁场景下赋能企业安全,F5推出BIG-IP Next Web应用防火墙
网络协议·tcp/ip·安全
很透彻16 小时前
【网络】传输层协议UDP
网络·网络协议·udp
你不讲 wood16 小时前
使用 Axios 上传大文件分片上传
开发语言·前端·javascript·node.js·html·html5