Node.js代码实例:简单Web服务端

news2024/11/21 3:33:58

文章目录

  • 前言
  • 代码仓库
  • 为什么要写一份Node.js简单Web服务端的代码实例?
  • 内容
  • 目录结构
  • 代码
    • server.js
    • index.html
    • index.css
    • index.js
    • value.html
  • 结果
  • 总结
  • 参考资料
  • 作者的话

前言

Node.js代码实例:简单Web服务端。


代码仓库

  • yezhening/Programming-examples: 编程实例 (github.com)
  • Programming-examples: 编程实例 (gitee.com)

为什么要写一份Node.js简单Web服务端的代码实例?

  • 想多了解一些技术知识,所以简单学习了Node.js
  • 写过C和C++的环境和网络编程,它们的处理很复杂。了解到Node.js底层使用Libuv网络异步I/O库,以事件驱动+异步I/O方式运行,适合处理网络I/O高并发的场景,和Go语言相似,具有互相比对的学习价值
  • 写过而且写的很多代码都是客户端/服务端(C/S)模型的网络传输,写一份关于Web服务端的传输,能够深入了解Web服务和HTTP原理

内容

  • 详细解析创建http服务端的流程、URL的组成、请求消息的结构和响应消息的结构
  • 通过网络传输,浏览器客户端向该Web服务端发送“GET”请求,服务端依据URL响应本地相应的HTML、CSS和JavaScript文件,并在客户端渲染显示页面

目录结构

simple_Web_server目录:

  • server.js文件
  • www目录

www目录:

  • index.html
  • index.css
  • index.js
  • value.html

代码

server.js

// 一、导入http模块
const http_module = require('http')    // HTTP相关
const path_module = require('path') // 字符串路径相关
const fs_module = require('fs')    // 文件系统相关

// 二、创建服务端对象
// 参数:可选项服务端如timeout和keepalive等配置,自动添加到‘request’请求事件的回调函数:当有客户端发起请求时,调用这个回调函数
// 返回值:http.server对象
const server = http_module.createServer()

const host = '127.0.0.1'    // 主机
const port = 8000   // 端口
const request_query_stringing_key = 'key'   // 请求url中,查询字符串的键
const site_root_directory = 'www'   // 网站根目录

// 三、服务端对象绑定‘request’请求事件,监听客户端请求
// emitter.on(eventName, listener)是node.js中的事件绑定方法
// 当有客户端发起请求时,调用这个回调函数:传入http.IncomingMessage请求对象和http.ServerResponse响应对象
server.on('request', (request, response) => {
    // 1. 获取http请求信息
    // http请求有3部分:请求行,请求头和请求体
    // 请求行有3部分:方法,url,http版本
    // (1)获取方法:“GET”,这里不需要
    // const request_method = request.method
    // (1)获取url:“/index.html?key=value”
    const request_url = request.url
    // (1)获取版本:“1.1”,这里不需要
    // const request_version = request.httpVersion   
    // (2)获取请求头,返回键值对object,这里不需要
    // const request_headers = request.headers 
    // (3)获取请求体,返回string。GET方法请求体一般为空,这里不需要
    // let request_body = ''
    // request.on('data', (chunk) => { // 请求绑定‘data’事件,数据按流传输,有数据时读取chunk为Buffer对象,自动转换为string
    //     request_body += chunk
    // })
    // request.on('end', () => { // 请求绑定‘end’事件,数据传输完成时触发
    //     console.log(request_body)
    // })

    //  2. 处理url。如http://127.0.0.1:8000/index.html?key=value
    // url有4部分:协议“http://”,地址主机名和端口“127.0.0.1:8000”,路径“/index.html”,查询字符串“?key=value”
    // (1)获取协议http,这里不需要
    // (2) 获取地址,这里不需要
    const absolute_url = 'http://' + host + ':' + port + request_url    // 获取请求的绝对url。如http://127.0.0.1:8000/index.html?key=value
    const request_path_query_string = new URL(absolute_url)  // 解析绝对url,获取路径和查询字符串。如:/index.html?key=value
    // (3)获取路径。如:/index.html
    const request_path = request_path_query_string.pathname
    // (4)获取查询字符串。返回object如:{'key' => 'value'}
    const request_query_string = request_path_query_string.searchParams
    const request_query_string_value = request_query_string.get(request_query_stringing_key)    // 获取查询字符串的值。如:通过'key'获取'value'

    // 3. 结合网络路径和查询字符串,映射为本地文件系统中的路径
    let fs_path = ""
    if (request_path === '/') {
        fs_path = path_module.join(__dirname, site_root_directory, "index.html")
        // 对于url为'/'的网络路径,映射为服务端js文件所在当前目录下,网站根目录下的index.html文件路径
        // 如:C:\Users\DSHH\Desktop\simple_Web_server\www\index.html
    } else if (request_path === '/index.html' && request_query_string_value === 'value') {
        fs_path = path_module.join(__dirname, site_root_directory, "value.html")
        // 对于url为'/index.html'的网络路径,查询字符串值为'value',映射为服务端js文件所在当前目录下,网站根目录下的value.html文件路径
        // 如:C:\Users\DSHH\Desktop\simple_Web_server\www\value.html
    } else {
        fs_path = path_module.join(__dirname, site_root_directory, request_path)
        // 对于其他网络路径,映射为服务端js文件当前目录下,网站根目录下的资源文件路径
        // 如url为:'/other.html',则本地路径为:如:C:\Users\DSHH\Desktop\simple_Web_server\www\other.html
        // 注意:对于其他资源如css、js、ico等请求,全都走这个分支
        // 如:C:\Users\DSHH\Desktop\simple_Web_server\www\index.css、C:\Users\DSHH\Desktop\simple_Web_server\www\favicon.ico
        // 注意:浏览器除了请求路径中的页面,可能会自动请求favicon.ico作为网页的图标,可不管
    }

    // 4. 读取本地文件系统相应的文件,设置http响应信息
    // http响应有3部分:响应行,响应头和响应体
    // 响应行有3部分:http版本,状态码,状态描述
    //(1) http版本,无需设置
    // (2) 状态码在下面读取文件时设置
    // (3) 状态描述无需设置,一般与状态码匹配
    // response.statusMessage = 'This is status message'
    // (4) 响应头
    // 注意:
    // 只需要依据文档类型设置mime类型让浏览器可以解析html、css和js文档
    // 否则当html、css、js分文件编写时,请求html会再次请求css和js文档,再次进入这个回调函数
    // 若mime类型为text/html,则无法解析css文档,css无法渲染
    // 设置编码为utf8支持中文显示不乱码
    const fs_path_ext_name = path_module.extname(fs_path) // 获取本地路径文件的扩展名,如:.css
    const fs_path_mime_type = fs_path_ext_name.slice(1)   // 获取mime类型中,text类型下的子类型名,如:css
    response.setHeader('content-type', `text/${fs_path_mime_type};charset=utf-8`)   // 拼接为:text/css;charset=utf-8
    // (5) 响应体,在下面读取文件时设置

    // 参数:文件路径和编码等可选项,回调函数
    // 当读取完成时,调用这个回调函数:传入错误Error和数据string对象
    fs_module.readFile(fs_path, 'utf8', (error, data) => {
        // 如果有错误,返回404资源不存在状态码和状态信息
        // 没有错误,返回读取的文件数据
        if (error) {
            response.statusCode = 404   // (2)设置状态码
            // 参数:流数据,可选项编码和回调函数
            // 返回值:bool,不需要
            response.write('<h1>404 未找到</h1>')   // (5)设置响应体
            // 参数:数据、编码和回调函数等可选项
            // 返回值:this,即end()的调用者response对象
            // 对每个响应可以调用多次write()写入数据,必须调用一次end()返回响应
            response.end()
        } else {
            response.statusCode = 200   // (2)设置状态码
            response.write(data)    // (5)设置响应体
            response.end()
        }
    })
})

// 四、启动服务端监听
// 参数:对于TCP,使用端口、地址、半连接和全连接队列和回调函数可选项
server.listen(port, host, () => {
    console.log(`Wen服务端运行在: http://${host}:${port}`)
})

index.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>Document</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <h1>这是index.html</h1>

    <script src="./index.js"></script>
</body>
</html>

index.css

h1 {
    color: blue;
}

index.js

alert('这是index.js')

value.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>Document</title>
</head>

<body>
    <h1>这是value.html</h1>
</body>

</html>

结果

运行Web服务端:

PS C:\Users\DSHH\Desktop\simple_Web_server> node server.js
Wen服务端运行在: http://127.0.0.1:8000

浏览器访问: http://127.0.0.1:8000/ 或 http://127.0.0.1:8000/index.html

在这里插入图片描述
在这里插入图片描述

浏览器访问: http://127.0.0.1:8000/index.html?key=value

在这里插入图片描述

浏览器访问: http://127.0.0.1:8000/other.html

在这里插入图片描述


总结

Node.js代码实例:简单Web服务端。


参考资料

  • Node.js (nodejs.org)
  • Node.js 中文网 (nodejs.cn)
  • 黑马程序员Node.js全套入门教程,nodejs新教程含es6模块化+npm+express+webpack+promise等_Nodejs实战案例详解_哔哩哔哩_bilibili
  • 尚硅谷2023版Node.js零基础视频教程,nodejs新手到高手_哔哩哔哩_bilibili

作者的话

  • 感谢参考资料的作者/博主
  • 作者:夜悊
  • 版权所有,转载请注明出处,谢谢~
  • 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
  • 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
  • 文章在认识上有错误的地方, 敬请批评指正
  • 望读者们都能有所收获

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/457552.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LVS-DR

系列文章目录 文章目录 系列文章目录一、1.2. 二、实验1.2. 总结 一、 1. 2. 二、实验 1. 先把四台机器都关闭防火墙和安全机制 vim /etc/sysconfig/selinux把selinux都改成disabled 在NFS里面建立两个共享目录 给文件执行权限并写入内容给html 和www vim /etc/expor…

【C++】C++中的类型转化

说起类型转化&#xff0c;我们在C语言之前的学习中可以了解到&#xff0c;类型转换可以分为两种情况&#xff1a;隐式类型转化&#xff1b;显示类型转化。但是为什么在c中还要继续对类型转化做文章呢&#xff1f;我们一起来看&#xff1a; 目录 1. C语言中的类型转换 2. C强制…

【Transformer系列(5)】Transformer代码超详细解读(Pytorch)

前言 前面几篇我们一起读了transformer的论文&#xff0c;更进一步了解了它的模型架构&#xff0c;这一篇呢&#xff0c;我们就来看看它是如何代码实现的&#xff01; &#xff08;建议大家在读这一篇之前&#xff0c;先去看看上一篇模型结构讲解 这样可以理解更深刻噢&…

Python 基础(十二):字典

❤️ 博客主页&#xff1a;水滴技术 &#x1f338; 订阅专栏&#xff1a;Python 入门核心技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; 文章目录 一、声明字典1.1 使用 {} 声明字典1.2 使用 dict 函数声明字典1.3 声明一个空的字典 二…

【数据结构】AVLTree

1.AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&#xff0c;两位俄罗斯的数G.M.Adelson-Velskii 和E.M.Landis在1962年 发明了一种解决上…

会话与会话技术(Session)

前言 Cookie将用户的信息保存在各自的浏览器中&#xff0c;并且可以在多次请求下实现数据的共享。但是如果当传递的信息较多时&#xff0c;Cookie技术会增大服务器程序处理的难度&#xff0c;因此&#xff0c;Servlet提供了另一种会话技术————Session&#xff0c;Session可…

跟李沐学AI——实用机器学习(入门版)

机器学习目录 2.1 探索性数据分析 2.2 数据清理 2.3 数据变换 2.4 特征工程 2.5 数据科学家的日常 Stanford University Practical machine learning 2.1 探索性数据分析 ​ 对目标的ftr数据进行处理&#xff0c;针对不同的信息做出不同的图形 输出数据集的行数和列数以及前十…

ArcGIS Pro地理空间数据处理完整工作流实训及python技术融合

GIS是利用电子计算机及其外部设备&#xff0c;采集、存储、分析和描述整个或部分地球表面与空间信息系统。简单地讲&#xff0c;它是在一定的地域内&#xff0c;将地理空间信息和 一些与该地域地理信息相关的属性信息结合起来&#xff0c;达到对地理和属性信息的综合管理。GIS的…

1、TI335x环境建立

记录裸机开发&#xff0c;TI A8系列处理器的AM335x过程&#xff0c;本次开发的是3352&#xff0c;在此基础上开发。 1、硬件准备&#xff1a; 已经测试调试ok的3352测试板&#xff0c;经过查看发现&#xff0c;am3352引出的下载接口是JTAG口&#xff0c;而我手里只有Jlink&…

Kubernetes---Pod调度、标签、配额、策略

静态pod 静态pod由user直接创建调用&#xff0c;不能迁移 由kebelet守护进程直接管理的pod&#xff0c;无需APIserver监管 kubelet监视每个静态pod 静态pod永远绑定到一个指定节点上的kubelet 静态pod spec不能引用其他API对象 静态pod配置路径/var/lib/kubelet/config.yaml里面…

CSS背景相关属性

一、背景颜色 属性名&#xff1a;background-color (bgc) 属性值&#xff1a;颜色取值&#xff1a;关键字&#xff0c;rgb表示法&#xff0c;rgba表示法&#xff0c;十六进制表示。 注&#xff1a; 背景颜色默认透明&#xff1a;rgba&#xff08;0&#xff0c;0&#xff0c…

C语言积锦

代码区&#xff1a;text 代码执行二进制码&#xff08;程序指令&#xff09; 具有共享、只读特性 数据区&#xff1a;1.初始化数据区data 2.未初始化数据区 bss 3.常量区 栈区&#xff1a;系统为每一个程序分配一个临时的空间 局部变量、函数信息、函数参数、数组。栈区大…

干货|Graphpad Prism也能做ERP图?So Easy!

Hello&#xff0c;大家好&#xff01; 这里是壹脑云科研圈&#xff0c;我是喵君姐姐~ 不知道你是否注意过这样一个现象。 在心理学大会报告的时候&#xff0c;专家经常会说一句话&#xff1a; 这个结果很漂亮&#xff01;&#xff01;&#xff01; 第一次听见的时候&#x…

K8s图形化管理工具Dasboard部署及使用

文章目录 一、Dashboard简介二、Dashboard部署安装三、配置Dashboard登入用户1、通过Token令牌登入2、通过kubeconfig文件登入 四、Dashboard创建容器 一、Dashboard简介 Kubernetes Dashboard是一个Web UI&#xff0c;用于管理Kubernetes集群中的应用程序和资源。它提供了一个…

使用wireshark抓包理解tcp协议和tls

首先下载安装wireshark 打开软件 1.选则自己连结的网络&#xff1b; 此时就会捕获的数据 2.加上端口过滤。 3.启动一个本地的http服务(这里采用的nodejs)&#xff1b; // server.js import koa from koa; const app new koa(); app.use(ctx > {ctx.body "hell…

托福听力专项 // Unit1 Listening for Main Ideas // Practice with Lectures // 共4篇

目录 Listening for Main Idea Lecture A a music class 单词 内容总结 Lecture B 单词 错题分析 Lecture C 单词 错题分析 Lecture D 单词 Listening for Main Idea Lecture A a music class 单词 evolve(v)to develop slowlyincorporate(v)to take in or includ…

Spring Boot使用(基础)

目录 1.Spring Boot是什么? 2.Spring Boot使用 2.1Spring目录介绍 2.2SpringBoot的使用 1.Spring Boot是什么? Spring Boot就是Spring脚手架,就是为了简化Spring开发而诞生的 Spring Boot的优点: 1.快速集成框架,提供了秒级继承各种框架,提供了启动添加依赖的功能 2.内…

修炼汇编语言第一章:汇编基础知识概述

目录 前言 一、汇编语言的组成 二&#xff1a;存储器 三&#xff1a;指令和数据 四&#xff1a;存储单元 五&#xff1a;CPU对存储器的读写 地址总线 控制总线 数据总线 前言 汇编语言是数据结构&#xff0c;操作系统&#xff0c;微机原理等重要课程的基础&#xff0…

【算法】冒泡排序

一.冒泡排序 主要思想&#xff1a; 反复交换相邻的元素&#xff0c;使较大的元素 逐渐冒泡到数组的末尾&#xff0c;从而实现排序的效果 实现过程&#xff1a; 1.遍历待排序数组&#xff0c;比较相邻的元素&#xff0c;如果前面的元素比后面的元素大&#xff0c; 就交换这两…

系统集成项目管理工程师 笔记(第八章:项目进度管理)

文章目录 8.1 规划项目进度管理 2938.1.1 规划项目进度管理的输入 2938.1.2 规划项目进度管理的工具与技术 2948.1.3 规划项目进度管理的输出 295 8.2 定义活动 2968.2.1 定义活动的输入 2968.2.2 定义活动的工具与技术 2968.2.3 定义活动的输出&#xff08;两清单、一属性&…