写代码太枯燥了?使用Express 实现的用户IP和本机IP 显示与名言提示功能

123 阅读11分钟

写代码太枯燥了?使用Express 实现的用户IP和本机IP 显示与名言提示功能

背景

写代码太枯燥,写个小功能打打鸡血。

获取用户的ip地址,随机生成一条名言

顺便介绍corsexpress.json,express.urlencoded() 中间件

image-20241113151613898.png 素材.gif

image-20241113151625212.png 使用 Node.jsExpress 构建一个简单的 Web 应用,结合 CORS(跨域资源共享)和 动态名言显示,根据用户的 IP 地址随机展示一条励志名言。搭建基本的 Web 服务器,还融合了对 JSON 数据文件的导入和利用。

项目结构

项目的目录结构如下:

project/
│
├── index.js项目入口
│
├── utils
│   └── redrun.js//工具函数
│   └── famous_words.json// 名言句子
│
└── package.json // 包依赖

项目入口index.js

import express from 'express'
import cors from 'cors'
// 获取服务器ip
import { getLocalIP } from './utils/redrun.js'
// 获取名言,这里使用esmodule模式,需要断言一下
import famous_words from './utils/famous_words.json' assert {type: "json"}
const app = express()
const port = 3000
// 处理跨域
app.use(cors())
// 这个中间件用于解析传入请求的 JSON 格式数据
app.use(express.json())
// 这个中间件用于处理 URL 编码的表单数据(也称为 application/x-www-form-urlencoded)。它主要用来解析客户端通过 HTML 表单提交的数据,通常是键值对的形式。
app.use(express.urlencoded({ extended: false }))
app.use((req, res) => {
   // 获取用户ip地址
  let ipRaw = req.ip;
  let ip = ipRaw.split(":").pop();
    // 随机返回一条名言
  const words = famous_words[Math.floor(Math.random() * famous_words.length)];
  res.send(`ip:${ip}${words}】`);
});
app.listen(port, () => {
  const words = famous_words[Math.floor(Math.random() * famous_words.length)];
    // 打印服务器本地ip
  console.log(`running:http://${getLocalIP()}:${port}`)
  console.log(`${words}`)
})
​
app.use(express.json())

app.use(express.json()) 这个中间件用于解析传入请求的 JSON 格式数据。在现代的 Web 应用中,许多前端框架(例如 React、Vue.js)会使用 JSON 格式发送数据,特别是在发送 POST 请求时。

app.use(express.json());

当客户端(例如浏览器或移动设备)向服务器发送包含 JSON 数据的请求时,express.json() 中间件会将请求体中的 JSON 数据解析为 JavaScript 对象,方便后续的处理。

例如,客户端发送如下请求:

POST /api/user
{
  "name": "John Doe",
  "age": 30
}

服务器端处理请求时,express.json() 会把请求体转换为一个对象:

app.post('/api/user', (req, res) => {
  const user = req.body;  // { name: 'John Doe', age: 30 }
  res.send(`User name: ${user.name}`);
});
app.use(express.urlencoded({ extended: false }))

app.use(express.urlencoded({ extended: false })) 这个中间件用于处理 URL 编码的表单数据(也称为 application/x-www-form-urlencoded)。它主要用来解析客户端通过 HTML 表单提交的数据,通常是键值对的形式。

这个中间件用于处理 URL 编码的表单数据(也称为 application/x-www-form-urlencoded)。它主要用来解析客户端通过 HTML 表单提交的数据,通常是键值对的形式。
  • extended: false 表示使用 querystring 模块来解析表单数据,即只能解析简单的字符串或数组形式的数据。
  • 如果将 extended: true,则会使用 qs 库来解析,允许更复杂的数据结构,如嵌套对象和数组。

示例

假设客户端通过表单提交如下数据:

<form method="POST" action="/submit">
  <input type="text" name="username" value="johndoe">
  <input type="number" name="age" value="30">
  <button type="submit">Submit</button>
</form>

服务器端可以通过 express.urlencoded() 解析表单数据:

app.post('/submit', (req, res) => {
  const { username, age } = req.body;  // { username: 'johndoe', age: 30 }
  res.send(`Username: ${username}, Age: ${age}`);
});

包依赖package.json

"type": "module",// esmodule和commonjs模式,默认为commonjs,这里使用module也就是esmodule模式

commonjs兼容esmodule导入导出,但是esmodule不完全兼容commonjs导出导出

esmodule是大趋势


{
  "name": "famous_words",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",// esmodule模式
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^1.7.3",
    "cors": "^2.8.5",
    "express": "^4.19.2",
  }
}
​

工具函数utils/redrun.js

import os from 'os'
// 获取本机的所有网络接口
const networkInterfaces = os.networkInterfaces();
​
// 遍历网络接口,获取有效的 IPv4 地址
export const getLocalIP = () => {
  for (let interfaceName in networkInterfaces) {
    for (let interfaceDetails of networkInterfaces[interfaceName]) {
      // 检查是否为 IPv4 地址,并且是局域网地址
      if (interfaceDetails.family === 'IPv4' && !interfaceDetails.internal) {
        return interfaceDetails.address;
      }
    }
  }
  return null;  // 如果没有找到合适的 IP 地址
}

一百条名言utils/famous_words.json

[  "人活在世,不过一场美丽的寄居。——简嫃",  "活着不一定要鲜艳,但一定要有自己的颜色。——张曙光",  "人类文化的悲哀,是流俗的易传、高雅的失传。——木心",  "在每个死胡同的尽头,都有另一个维度的天空。——廖一梅",  "生命的意义在于付出,在于给予,而不是在于接受,也不是在于争取。——巴金",  "善于利用零星时间的人,才会做出更大的成绩来。——华罗庚",  "少而好学,如日出之阳;壮而好学,如日中之光;老而好学,如炳烛之明。——刘向",  "人生的价值,即以其人对于当代所做的工作为尺度。 —— 徐玮",  "芸芸众生,孰不爱生?爱生之极,进而爱群。 —— 秋瑾",  "生活真象这杯浓酒,不经三番五次的提炼呵,就不会这样可口!—— 郭小川",  "纵使黑夜吞噬了一切,太阳还可以重新回来。——汪国真",  "一条路并不因为它路边长满荆棘而丧失其美丽,旅行者照旧向前进。——罗曼·罗兰",  "如同明日将死那样生活,如同永远不死那样求知。——甘地",  "愿望是半个生命,淡漠是半个死亡。——纪伯伦",  "不存在十全十美的文章,如同不存在彻头彻尾的绝望。——村上春树",  "生命的定义就是拥有明天。——冯骥才",  "开成花灾的玫瑰不是灿烂,而是荒凉。——严歌苓",  "与其在绝望和挣扎中苟活,不如在希冀和盼望中死亡。——纪伯伦",  "在逆风里把握方向,做暴风雨中的海燕,做不改颜色的孤星。——余光中",  "人一辈子都在高潮——低潮中浮沉,唯有庸碌的人,生活才如死水一般。——傅雷",  "在自己身上,克服这个时代。——尼采",  "万人都要将火熄灭,我一人独将此火高高举起。——海子",  "历史是一堆灰烬,但灰烬深处有余温。——黑格尔",  "人类文化的悲哀,是流俗的易传、高雅的失传。——木心",  "此处果有可乐,我即别无所思。——林语堂",  "人要有出世的精神才可以做入世的事业。——朱光潜",  "名不显时心不朽,再挑灯火看文章。——唐寅",  "教育不是注满一桶水,而是点燃一把火。 ——叶芝",  "不可乘快而多事,不可因倦而鲜终。——菜根谭",  "一个人的行动,比他所说的话,更有详细的表现。——卡耐基",  "一花凋零,荒芜不了整个春天。——巴尔扎克",  "读书使人充实,思考使人深邃,交谈使人清醒。——富兰克林",  "青春是一种持续的陶醉,是理智的狂热。——拉罗什富科",  "只有永远躺在泥坑里的人,才不会再掉进坑里。——黑格尔",  "每一个不曾起舞的日子,都是对生命的辜负。——尼采",  "人生应该如蜡烛一样,从顶燃到底,一直都是光明的。 —— 萧楚女",  "真正的人生,只有在经过艰难卓绝的斗争之后才能实现。——塞涅卡",  "顽强的毅力可以征服世界上任何一座高峰。——狄更斯",  "早知今日读书是,悔作从前任侠非。——李欣",  "生活最沉重的负担不是工作,而是无聊。——罗曼·罗兰",  "千里之行,始于足下。——老子",  "少年易学老难成,一寸光阴不可轻。——朱熹",  "敏而好学,不耻下问。——孔子",  "天生我材必有用。——李白",  "人生贵相知,何用金与钱。——李白",  "海内存知已,天涯若比邻。——王勃",  "月缺不改光,剑折不改刚。——梅尧臣",  "莫愁前路无知已,天下谁人不识君。——高适",  "海纳百川有容乃大;壁立千仞无欲则刚。——林则徐",  "穷则独善其身,达则兼济天下。——孟子",  "自由自由,多少罪恶假汝之名以行。——罗兰夫人",  "茅草屋顶下住着自由人,大理石和黄金下栖息着奴隶。——塞涅卡",  "即使被关在果壳之中,我仍自以为是无限宇宙之王。——莎士比亚",  "我不同意你说的每一句话,但我誓死捍卫你说话权利的自由。——伏尔泰",  "生命,那是自然付给人类去雕琢的宝石。——诺贝尔",  "书是人类进步的阶梯,终生的伴侣,最诚挚的朋友。——高尔基",  "为伟大的事业捐躯,从来就不能算作失败。——拜伦",  "新的方法和概念,常常比解决问题本身更重要。——华罗庚",  "成大事不在于力量的大小,而在于能坚持多久。——塞·约翰生",  "人所缺乏的不是才干而是志向,不是成功的能力而是勤劳的意志。——部尔卫",  "只有经历过地狱般的磨砺,才能练就创造天堂的力量;只有流过血的手指,才能弹出世间的绝响。——泰戈尔",  "立志用功如种树然,方其根芽,犹未有干;及其有干,尚未有枝;枝而后叶,叶而后花。——王守仁",  "青春是一个普通的名称,它是幸福美好的,但它也是充满着艰苦的磨炼。——高尔基",  "志向是天才的幼苗,经过热爱劳动的双手培育,在肥田沃土里将成长为粗壮的大树。——苏霍姆林斯基",  "心若改变,你的态度跟着改变;态度改变,你的习惯跟着改变;习惯改变,你的性格跟着改变;性格改变,你的人生跟着改变。——亚伯拉罕·马斯洛",  "若天压我,劈开那天,若地拘我,踏碎那地,我等生来自由身,谁敢高高在上——今何在",  "有两件事我最憎恶:没有信仰的博才多学和充满信仰的愚昧无知。——爱默生",  "谁终将声震人间,必长久深自缄默;谁终将点燃闪电,必长久如云漂泊。——尼采",  "理想主义者是不可救药的:如果他被扔出了他的天堂,他会再制造出一个理想的地狱。——尼采",  "仿佛前世的密约,注定我们要在今生抵掌,然后一起创世,或者再次站成一排,慷慨赴死。——野夫",  "如果是玫瑰,它总会开花的。——歌德",  "失败是坚忍的最后考验。——俾斯麦",  "辛勤的蜜蜂永没有时间悲哀。——布莱克",  "对于不屈不挠的人来说,没有。——俾斯麦",  "冬天已经到来,春天还会远吗? —— 雪莱",  "生命不止,奋斗不息。——卡莱尔",  "人生不是一种享乐,而是一桩十分沉重的工作。——列夫·托尔斯泰",  "时间是伟大的作者,她能写出未来的结局。——卓别林",  "志向和热爱是伟大行为的双翼。——歌德",  "我这个人走得很慢,但是我从不后退。——亚伯拉罕·林肯",  "一个人几乎可以在任何他怀有无限热忱的事情上成功。 ——查尔斯·史考伯",  "深窥自己的心,而后发觉一切的奇迹在你自己。——培根",  "失败也是我需要的,它和成功对我一样有价值。——爱迪生",  "人需要真理,就像瞎子需要明快的引路人一样。——高尔基",  "任何问题都有解决的办法,无法可想的事是没有的。——爱迪生",  "每一种挫折或不利的突变,是带着同样或较大的有利的种子。——爱默生",  "只要朝着一个方向努力,一切都会变得得心应手。——勃朗宁",  "人的一生可能燃烧也可能腐朽,我不能腐朽,我愿意燃烧起来! —— 奥斯特洛夫斯基",  "你若要喜爱你自己的价值,你就得给世界创造价值。 —— 歌德",  "生活的情况越艰难,我越感到自己更坚强,甚而也更聪明。——高尔基",  "如果我比笛卡尔看得远些,那是因为我站在巨人们的肩上的缘故。——牛顿",  "人生不是一种享乐,而是一桩十分沉重的工作。 —— 列夫·托尔斯泰",  "人只有献身于社会,才能找出那短暂而有风险的生命的意义。 —— 爱因斯坦",  "一个人能否有成就,只看他是否具备自尊心与自信心两个条件。——苏格拉底",  "生活在我们这个世界里,不读书就完全不可能了解人。——高尔基",  "没有目的,就做不成任何事情;目的渺小,就做不成任何大事——狄德罗",  "进步,意味着目标不断前移,阶段不断更新,它的视影不断变化。——雨果",  "你以为挑起生活的担子是勇气,其实去过自己真正想要的生活才更需要勇气。——萨姆门德斯",  "生活赋予我们一种巨大的和无限高贵的礼品,这就是青春:充满着力量,充满着期待志愿,充满着求知和斗争的志向,充满着希望信心和青春。——奥斯特洛夫斯",  "感情有着极大的鼓舞力量,因此,它是一切道德行为的重要前提,谁要是没有强烈的志向,也就不能够热烈地把这个志向体现于事业中。——凯洛夫"]

启动和运行

首先确保电脑上有node环境!

  1. 下载项目

  2. 安装依赖: 确保你已安装必要的 npm 包,如 expresscors。你可以使用以下命令安装这些依赖:

    npm install install
    
  3. 运行应用: 使用以下命令启动服务器:

    node index.js
    
  4. 访问应用: 打开浏览器,访问 http://localhost:3000,你将看到包含 IP 地址和随机名言的响应。

拜拜

我这个人走得很慢,但是我从不后退。——亚伯拉罕·林肯