• 初学Nodejs(3):http模块


    初学Nodejs

    http模块

    1、概念

    • 什么是客户端与服务端
      在网络节点中,负责消费资源的电脑,叫做客户端;负责对外提供网络资源的电脑叫做服务器

    • http模块是Nodejs官方提供的、用来创建web服务器的模块。通过http模块提供的http.createServe()方法,就能方便的把一台普通的电脑变成一台web服务器,从而对外提供web资源服务。

    2、http模块作用

    • 服务器和普通电脑的区别在于,服务器上安装了web服务器软件,例如:IIS、Apache等。通过安装这些服务器软件,就能把一台普通的电脑变成台web服务器。

    • 在Nodejs中,并不需要第三方web服务器软件,因为可以基于nodejs自带的http模块,通过几行简单的代码,就能轻松的手写一个服务器软件,从而对外提供web服务

    3、使用http模块创建基本web服务器

    3.1 基本步骤

    • 导入http模块
    • 创建web服务器实例
    • 为服务器实例绑定request事件,监听客户端的请求
    • 启动服务器
    // 导入http模块
    const http = require('http')
    
    // 创建web服务器实例
    const server = http.createServer()
    
    // 为web服务器绑定request事件,监听客户端请求
    server.on('request', function (req, res) {
        // req是请求对象,包含于客户端相关的数据和属性,例如req.url表示客户端请求的URL地址,req.method是客户端的method请求类型
        console.log('someone visit our web server');
    
        const str1 = `Your request url is ${req.url},and request method is ${req.method}`
        console.log(str1);
    
        const str2 = `您请求的URL地址是${req.url},请求的method类型为${req.method}`
        // 设置响应头,防止中文乱码(告诉浏览器,服务器这边将返回text/html类型的数据)
        res.setHeader('Content-Type','text/html; charset=utf-8')
    
        // 向客户端发送指定的内容,并结束这次请求的处理过程
        res.end(str2);
    
    })
    
    // 启动服务器
    server.listen(8080, function () {
        console.log('server running at http://127.0.0.1:8080')
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    3.2 req请求对象的使用

    只要服务器接收到了客户端的请求,就会调用server.on()为服务器绑定的request事件处理函数。可以通过如下的方式访问与客户端相关的数据或属性。

    server.on('request',(req) => {
    	// req是请求对象,包含于客户端相关的数据和属性,例如req.url表示客户端请求的URL地址,req.method是客户端的method请求类型
    	const str = 'Your request url is ${req.url},and request method is ${req.method}'
    	console.log(str);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5

    需要注意的是req.url输出的是端口号后面的地址,并不是一个完整地址

    3.3 res响应对象的使用

    在服务器的request事件处理函数中,如果想访问服务器相关的数据或属性,可以使用如下的方式;

    // 为web服务器绑定request事件,监听客户端请求
    server.on('request', function (req, res) {
        // req是请求对象,包含于客户端相关的数据和属性,例如req.url表示客户端请求的URL地址,req.method是客户端的method请求类型
        console.log('someone visit our web server');
        
        const str = `Your request url is ${req.url},and request method is ${req.method}`
        // 向客户端发送指定的内容,并结束这次请求的处理过程
        res.end(str);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.4 解决中文乱码问题

    当调用res.end()方法向客户端发送中文内容的时候会出现乱码问题,此时需要手动设置内容的编码,这里可以通过设置响应头 Content-Type 的值为text/html; charset=utf-8 解决中文乱码问题

    res.setHeader(‘Content-Type','text/html;charset=utf-8')
    
    • 1
    // 为web服务器绑定request事件,监听客户端请求
    server.on('request', function (req, res) {
        // req是请求对象,包含于客户端相关的数据和属性,例如req.url表示客户端请求的URL地址,req.method是客户端的method请求类型
        console.log('someone visit our web server');
    
        const str = `您请求的URL地址是${req.url},请求的method类型为${req.method}`
        res.setHeader('Content-Type','text/html; charset=utf-8')
        // 向客户端发送指定的内容,并结束这次请求的处理过程
        res.end(str);
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.5 数据处理

    1、获取post请求,请求头为application/x-www-form-urlencoded,表单类型的数据

    const http = require('http')
    const queryString = require('query-string') // 解析查询字符串为js对象或者js对象转查询字符串
    const server = http.createServer()
    
    server.on('request', function (req, res) {
        // console.log(req)
    
        // 设置编码,防止中文乱码
        res.setHeader('Content-Type', 'text/html; charset=utf-8')
        // 处理跨域
        res.setHeader("Access-Control-Allow-Origin", "*");
    
        let data = ''
    	let result = ''
    	// 处理数据
    	// 可以通过if(req.method=='post')或者if(req.url=='./xxx')来决定获取哪个请求或者路由的数据,我这为简便就不写了
        req.on('data', chunk => {
            // 请求头类型为application/x-www-form-urlencoded/charset=utf-8的形式
            // 将每次收到的数据片段拼接到 data 变量中
            console.log(chunk, "chunk ================="); // chunk是一个buffer类型的数据
            // 通过拼接可以一步转buffer为普通字符串,或者调用一下toString()方法也可以转为字符串
            data += chunk
            // data = chunk.toString()
            console.log(data, "data ===============");
    
            // 将查询字符串转为js对象
           	result = queryString.parse(data)
            console.log(result, "result ============")
        })
    	
    	// 返回数据
        req.on('end', () => {
            res.end(JSON.parse(result)) // 将js对象转为json对象返回
        })
    })
    
    server.listen(8080, function () {
        console.log("服务器启动成功,监听8080端口...")
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    2、获取get请求,请求头为application/x-www-form-urlencoded,表单类型的数据

    对于get请求,一般参数会在url上,所以要先从url上截取参数

    const http = require('http')
    const server = http.createServer()
    const url = require('url') // 处理url路径的模块,这里用来截取查询字符串
    
    server.on('request', function (req, res) {
    
        // 设置编码,防止中文乱码
        res.setHeader('Content-Type', 'text/html; charset=utf-8')
        // 处理跨域
        res.setHeader("Access-Control-Allow-Origin", "*");
    
        // 参数放在url中,从url截取字符串并转为js对象
        const queryObject = url.parse(req.url, true).query;
    
        res.end(JSON.stringify(queryObject))
    })
    
    server.listen(8080, function () {
        console.log("服务器启动成功,监听8080端口...")
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3、如果接收到的参数是json字符串,那么同理,先想办法将json字符串转为js对象(例如JSON.parse()方法将json对象转为js对象),再进行其他处理并返回啥的…
    对于get请求,由于不存在请求体,所以需要将json数据拼接在url上,对于参数少的情况这种办法行得通,但如果数据过多,那么会导致url很长,浏览器导航栏会截取部分url,导致出现问题,所以最好还是使用post请求来处理json数据。
    如下:

    const http = require('http')
    const server = http.createServer()
    
    server.on('request', function (req, res) {
        console.log(req.url);
        // 设置编码,防止中文乱码
        // res.setHeader('Content-Type', 'text/html; charset=utf-8')
        // 处理跨域
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Allow-Methods", "*");
        res.setHeader("Access-Control-Allow-Headers", "Content-Type,XFILENAME,XFILECATEGORY,XFILESIZE");
    
        let data = ''
        // 可以通过if(req.method=='post')或者if(req.url=='./xxx')来决定获取哪个请求或者路由的数据,我这为简便就不写了
        // 获取数据
        req.on('data', chunk => {
            // 请求头类型为application/json;charset=utf-8的形式
            // 将每次收到的数据片段拼接到 data 变量中
            console.log(chunk, "chunk ================="); // chunk是一个buffer类型的数据
            // 通过拼接可以一步转buffer为普通字符串,或者调用一下toString()方法也可以转为字符串
            data += chunk
            // data = chunk.toString()
            console.log(data, "data ===============");
            
           	// 使用JSON.parse()将json转为js对象,对数据进行一些处理啥的
    		// ...
        })
    
        req.on('end', () => {
            // 返回json数据
            res.end(data)
        })
    })
    
    server.listen(8080, function () {
        console.log("服务器启动成功,监听8080端口...")
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    3.6 根据不同的url响应不同的html内容

    1、核心实现步骤
    (1)获取请求的url地址
    (2)设置下默认的相应内容为 ’404 Nod found’
    (3)判断用户请求的是否为/ 或者 其他url地址
    (4)判断用户请求的是否为指定页面
    (5)设置Content-Type响应头,防止中文乱码
    (6)使用res.end()把内容响应给客户端

    server.on('request', (req, res) => {
        // 1、获取请求的url地址
        const url = req.url
        
        // 2、设置默认的内容为404 not found
        let content = '

    404 Not Found

    '
    // 3、判断用户请求的url地址,显示对应的页面 if(url === '/' || url === '/index.html'){ content = '

    首页

    '
    }else if(url === '/about.html'){ content = '

    关于页面

    '
    } // 4、中文乱码处理 res.setHeader('Content-Type','text/html; charset=utf-8') // 5、服务器响应数据 res.end(content) })
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    3.6 例题

    有如下js/html/css实现的动态页面,目录结构如下

    - HttpTest根目录
    HttpTest/web
    HttpTest/web/main.html
    HttpTest/web/main.css
    HttpTest/web/main.js
    HttpTest/server.js
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    实现的效果为:
    请添加图片描述

    • HttpTest/web/main.html
    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Documenttitle>
        <link rel="stylesheet" href="./main.css">
    head>
    
    <body>
        <div class="father">
            <div class="son">
    
            div>
        div>
    
        <script src="./main.js">script>
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • HttpTest/web/main. css
    .father {
        width: 300px;
        height: 300px;
        background-color: skyblue;
    }
    
    .son {
        width: 100px;
        height: 100px;
        background-color: pink;
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • HttpTest/web/main.js
    window.onload = function () {
        var father = document.getElementsByClassName('father')[0];
        father.onclick = function () {
            alert('天蓝色')
        }
        var son = document.getElementsByClassName('son')[0]
        son.onclick = function (event) {
            alert('粉色')
            event.stopPropagation();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • HttpTest/server.js
    const fs = require('fs')
    const path = require('path')
    const http = require('http')
    
    const server = http.createServer()
    
    // 为web服务器绑定request事件,监听客户端请求
    server.on('request',(req,res)=>{
        // 获取客户端请求的url地址
        let url = req.url;
        // console.log(url);
        
        // url值有如下:
        /**
         * /web/main.html
         * /web/main.css
         * /web/main.js
         */
    
        // 将资源的请求url地址映射为文件的存放路径
        const fpath = path.join(__dirname,url)
        // console.log(fpath);
        
        // 根据映射过来的路径读取文件内容
        fs.readFile(fpath,(err,data) => {
            // 如果读取失败,向客户端响应固定的‘错误信息’
            if(err) return res.end('404 not found')
            // 如果读取成功,将读取成功的内容响应给客户端
            res.end(data)
        })
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    上述例题中的访问过程如下图:
    在这里插入图片描述

    通过访问http://127.0.0.1:8080/web/main.html可以访问到页面,但url地址中需要手动添加一个web文件夹,显得url很长,下面通过优化资源请求访问路径来缩短url

    3.6 例题:优化资源请求访问路径
    • HttpTest/server.js
    const fs = require('fs')
    const path = require('path')
    const http = require('http')
    
    const server = http.createServer()
    
    // 为web服务器绑定request事件,监听客户端请求
    server.on('request',(req,res)=>{
        // 获取客户端请求的url地址
        let url = req.url;
        console.log(url);
        // url值为如下:
        /**
         * /web/main.html
         * /web/main.css
         * /web/mian.js
         */
    
        // 将资源的请求url地址映射为文件的存放路径
        // const fpath = path.join(__dirname,url)
    
    // =====================================
        // 优化请求路径
        let fpath = ''
    
        if(url === '/'){
            fpath = path.join(__dirname,'./web/main.html')
        }else {
            fpath = path.join(__dirname,'./web',url)
        }
    
        console.log(fpath);
    // =====================================
    
        // 根据映射过来的路径读取文件内容
        fs.readFile(fpath,(err,data) => {
            // 如果读取失败,向客户端响应固定的‘错误信息’
            if(err) return res.end('404 not found')
            // 如果读取成功,将读取成功的内容响应给客户端
            res.end(data)
        })
    })
    
    // 启动服务器,监听8080端口
    server.listen('8080',() => {
        console.log('server running at http://127.0.0.1:8080');
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    这样就可以直接通过输入路径127.0.0.1/main.html来访问到页面,而不用在路径中手动添加一个web

  • 相关阅读:
    DataEase 介绍、使用技巧
    动态链接(地址无关技术)
    玄子Share- IDEA 2023 Web 热部署
    垃圾回收与算法
    计算机毕设(附源码)JAVA-SSM基于框架的秧苗以及农产品交易网站
    KNN 和 SVM 图片分类 任务 代码及细节分享
    【MongoDB】索引 - 复合索引
    Educational Codeforces Round 130 (Rated for Div. 2) A--C
    一文了解模型量化中的QAT和PTQ
    vue截取URL中的参数
  • 原文地址:https://blog.csdn.net/lalala_dxf/article/details/126455963