轻松搭建远程Node.js服务端,让你的应用在公共网络中畅行无阻!

文章目录

  • 前言
  • 1.安装Node.js环境
  • 2.创建node.js服务
  • 3. 访问node.js 服务
  • 4.内网穿透
    • 4.1 安装配置cpolar内网穿透
    • 4.2 创建隧道映射本地端口
  • 5.固定公网地址

前言

Node.js 是能够在服务器端运行 JavaScript 的开放源代码、跨平台运行环境。Node.js 由 OpenJS Foundation(原为 Node.js Foundation,已与 JS Foundation 合并)持有和维护,亦为 Linux 基金会的项目。Node.js 采用 Google 开发的 V8 运行代码,使用事件驱动、非阻塞和异步输入输出模型等技术来提高性能,可优化应用程序的传输量和规模。这些技术通常用于资料密集的即时应用程序。

Node.js 大部分基本模块都用 JavaScript 语言编写。在 Node.js 出现之前,JavaScript 通常作为客户端程序设计语言使用,以JavaScript 写出的程序常在用户的浏览器上运行。Node.js 的出现使 JavaScript 也能用于服务端编程。Node.js 含有一系列内置模块,使得程序可以脱离 Apache HTTP Server 或 IIS,作为独立服务器运,下面将介绍如何简单几步实现远程公共网络下访问windwos node.js的服务端。

1.安装Node.js环境

官网下载node.js,我们选择64位一键安装

https://nodejs.org/zh-cn/download/

image-20230302141011787

安装好后我们打开cmd,输入命令有正常出来版本号,表示安装成功,一键安装版,默认会配置环境变量。

node -v

image-20230302150424377

2.创建node.js服务

这里我们在本地创建一个简单的nodejs服务,创建一个贪吃蛇页面小游戏来进行演示。

首先在本地创建一个文件夹,并在文件夹中新建2个文件,一个是js文件和一个html文件,需要放在同个目录下,然后使用vscode打开。

  • game.html文件
  • nodetest.js文件

image-20230302155043387

game.html添加如下html代码并保存,以下代码是一个html页面小游戏(贪吃蛇)

<!DOCTYPE html>
<html>
<head><title>贪吃蛇</title><meta charset="UTF-8"><meta name="keywords" content="贪吃蛇"><meta name="Description" content="这是一个初学者用来学习的小游戏"><style type="text/css">*{margin:0;}.map{margin:100px auto;height:600px;width:900px;background:#00D0FF;border:10px solid #AFAEB2;border-radius:8px;}</style>
</head><body>
<div class="map">
<canvas id="canvas" height="600" width="900"></canvas>
</div><script type="text/javascript">//获取绘制工具/*var canvas = document.getElementById("canvas");var ctx = canvas.getContext("2d");//获取上下文ctx.moveTo(0,0);ctx.lineTo(450,450);*/var c=document.getElementById("canvas");var ctx=c.getContext("2d");/*ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(450,450);ctx.stroke();*/var snake =[];//定义一条蛇,画蛇的身体var snakeCount = 6;//初始化蛇的长度var foodx =0;var foody =0;var togo =0;function drawtable()//画地图的函数{for(var i=0;i<60;i++)//画竖线{ctx.strokeStyle="black";ctx.beginPath();ctx.moveTo(15*i,0);ctx.lineTo(15*i,600);ctx.closePath();ctx.stroke();}for(var j=0;j<40;j++)//画横线{ctx.strokeStyle="black";ctx.beginPath();ctx.moveTo(0,15*j);ctx.lineTo(900,15*j);ctx.closePath();ctx.stroke();}for(var k=0;k<snakeCount;k++)//画蛇的身体{ctx.fillStyle="#000";if (k==snakeCount-1){ctx.fillStyle="red";//蛇头的颜色与身体区分开}ctx.fillRect(snake[k].x,snake[k].y,15,15);//前两个数是矩形的起始坐标,后两个数是矩形的长宽。}//绘制食物	ctx.fillStyle ="black";ctx.fillRect(foodx,foody,15,15);ctx.fill();}function start()//定义蛇的坐标{//var snake =[];//定义一条蛇,画蛇的身体//var snakeCount = 6;//初始化蛇的长度for(var k=0;k<snakeCount;k++){snake[k]={x:k*15,y:0};}drawtable();addfood();//在start中调用添加食物函数}function addfood(){foodx = Math.floor(Math.random()*60)*15; //随机产生一个0-1之间的数foody = Math.floor(Math.random()*40)*15;for (var k=0;k<snake;k++){if (foodx==snake[k].x&&foody==sanke[k].y)//防止产生的随机食物落在蛇身上{	addfood();}}}	function move(){switch (togo){case 1: snake.push({x:snake[snakeCount-1].x-15,y:snake[snakeCount-1].y}); break;//向左走case 2: snake.push({x:snake[snakeCount-1].x,y:snake[snakeCount-1].y-15}); break;case 3: snake.push({x:snake[snakeCount-1].x+15,y:snake[snakeCount-1].y}); break;case 4: snake.push({x:snake[snakeCount-1].x,y:snake[snakeCount-1].y+15}); break;case 5: snake.push({x:snake[snakeCount-1].x-15,y:snake[snakeCount-1].y-15}); break;case 6: snake.push({x:snake[snakeCount-1].x+15,y:snake[snakeCount-1].y+15}); break;default: snake.push({x:snake[snakeCount-1].x+15,y:snake[snakeCount-1].y});}snake.shift();//删除数组第一个元素ctx.clearRect(0,0,900,600);//清除画布重新绘制isEat();isDead();drawtable();} 			function keydown(e){switch(e.keyCode){case 37: togo=1; break;case 38: togo=2; break;case 39: togo=3; break;case 40: togo=4; break;case 65: togo=5; break;case 68: togo=6; break;}}function isEat()//吃到食物后长度加1{if(snake[snakeCount-1].x==foodx&&snake[snakeCount-1].y==foody){addfood();snakeCount++;snake.unshift({x:-15,y:-15});}}//死亡函数function isDead(){if (snake[snakeCount-1].x>885||snake[snakeCount-1].y>585||snake[snakeCount-1].x<0||snake[snakeCount-1].y<0){window.location.reload();}}document.onkeydown=function(e)
{keydown(e);} 
window.onload = function()//调用函数
{ start();setInterval(move,150);drawtable();}
</script>
</body>
</html>

nodetest.js文件添加如下js代码,以下代码意思是开启一个http服务,设置监听3000端口号

const http = require('http');//加载文件模块
const fs = require("fs");const hostname = '127.0.0.1';
//端口
const port = 3000;const server = http.createServer((req, res) => {res.statusCode = 200;res.setHeader('Content-Type', 'text/html');fs.readFile('./game.html', (err, data) => {if (err) throw err;console.log(data.toString);res.end(data);});});server.listen(port, hostname, () => {console.log(`Server running at http://${hostname}:${port}/`);
});

3. 访问node.js 服务

当我们编写好相关代码后,我们开始启动服务.在vscode控制台输入命令【注意需要进入到相应的文件目录下执行命令】

node .\nodetest.js

image-20230302170633966

有正常返回提示服务在本地3000端口下,我们打开浏览器,访问http://127.0.0.1:3000/,出现贪吃蛇界面表示成功【游戏控制:键盘上下左右键】

image-20230302171105342

4.内网穿透

这里我们使用cpolar来进行内网穿透,支持http/https/tcp协议,不限制流量,无需公网IP,也不用设置路由器,使用简单。

4.1 安装配置cpolar内网穿透

cpolar官网:https://www.cpolar.com/

访问cpolar官网,注册一个账号,然后下载并安装客户端,具体安装教程可以参考官网文档教程。

  • windows系统:在官网下载安装包后,双击安装包一路默认安装即可。
  • linux系统:支持一键自动安装脚本,详细请参考官网文档——入门指南

20230130105715

4.2 创建隧道映射本地端口

cpolar安装成功后,在浏览器上访问本地9200端口http://localhost:9200,使用cpolar邮箱账号登录。

20230130105810

点击左侧仪表盘的隧道管理——创建隧道,创建一个指向本地3000端口的http隧道

  • 隧道名称:可自定义命名,注意不要与已有的隧道名称重复
  • 协议:选择http
  • 本地地址:3000
  • 域名类型:免费选择随机域名
  • 地区:选择China vip

点击创建

image-20230302171633772

隧道创建成功后,点击左侧的状态——在线隧道列表,查看所生成的公网地址,然后复制地址

image-20230302171740715

打开浏览器器,我们使用上面公网地址进行访问,至此,我们成功将本地·node.js 服务发布到了公网地址

image-20230302171817498

5.固定公网地址

由于以上使用cpolar所创建的隧道使用的是随机公网地址,24小时内会随机变化,不利于长期远程访问。因此我们可以为其配置二级子域名,该地址为固定地址,不会随机变化。

  • 保留一个二级子域名

登录cpolar官网,点击左侧的预留,选择保留二级子域名,设置一个二级子域名名称,点击保留,保留成功后复制保留的二级子域名名称

image-20230302172317079

保留成功后复制保留的二级子域名地址

image-20230302172454064

  • 配置二级子域名

访问http://127.0.0.1:9200/,登录cpolar web UI管理界面,点击左侧仪表盘的隧道管理——隧道列表,找到所要配置的3000隧道,点击右侧的编辑

image-20230302172856768

修改隧道信息,将保留成功的二级子域名配置到隧道中

  • 域名类型:选择二级子域名
  • Sub Domain:填写保留成功的二级子域名

点击更新

image-20230302172806823

更新完成后,打开在线隧道列表,此时可以看到公网地址已经发生变化,地址名称也变成了保留过的二级子域名名称,将其复制下来

image-20230302172935943

然后使用固定http地址打开浏览器访问

image-20230302173012863
访问成功,现在这个公网地址是固定的了,不会随机变化。成功通过cpolar内网穿透,实现在外远程访问nodejs服务,无需公网IP ,也不用设置路由器。

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

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

相关文章

linux安装 MySQL8 并配置开机自启动

目录 1.下载 mysql 安装包 2.上传并解压 mysql 3.修改 mysql 文件夹名 4.创建mysql 用户和用户组 5.数据目录 &#xff08;1&#xff09;创建目录 &#xff08;2&#xff09;赋予权限 6.初始化mysql &#xff08;1&#xff09;配置参数 &#xff08;2&#xff09;配置环…

ChatGPT应用于高职教育的四大潜在风险

目前&#xff0c;ChatGPT还是一种仍未成熟的技术&#xff0c;当其介入高职教育生态后&#xff0c;高职院校师生在享受ChatGPT带来的便利的同时&#xff0c;也应该明白ChatGPT引发的风险也会随之进入高职教育领域&#xff0c;如存在知识信息、伦理意识与学生主体方面的风险与挑战…

爬虫异常处理:异常捕获与容错机制设计

作为一名专业的爬虫程序员&#xff0c;每天使用爬虫IP面对各种异常情况是我们每天都会遇到的事情。 在爬取数据的过程中&#xff0c;我们经常会遇到网络错误、页面结构变化、被反爬虫机制拦截等问题。在这篇文章中&#xff0c;我将和大家分享一些关于如何处理爬虫异常情况的经…

SpringBoot(二)

###SpringBoot原理分析 ###SpringBoot监控 ###SpringBoot项目部署 #SpringBoot自动配置 Condition&#xff1a;&#xff08;条件&#xff09; Condition是在Spring4.0增加的条件判断功能&#xff0c;通过这个功能可以实现选择性的创建Bean操作 SpringBoot是如何知道要创建…

隧道vs免费爬虫ip:为何要选择隧道爬虫ip?

在网络爬虫的世界中&#xff0c;爬虫ip是一项关键技术&#xff0c;它可以帮助我们隐藏身份、突破限制、提高抓取效率。但是&#xff0c;在选择爬虫ip时&#xff0c;我们常常会面对隧道爬虫ip和免费爬虫ip之间的抉择。在本文中&#xff0c;我们将探讨隧道爬虫ip相对于免费爬虫ip…

ROS_LINUX入门学习笔记=2=

B站ros机器人工匠阿杰入门教程 rqt_robot_steering 控制小乌龟 在index ros .rog中查找相关的包&#xff1a;ros_index 下图是rqt_robot_steering的简介 其中可以查看github源码地址 website可以查看效果图 下载相关的包 sudo apt install ros-kinetic-rqt-robot-steering …

会计如何使用ChatGPT提高工作效率

文章目录 ChatGPT改变了会计行业微软重新定义了PC交互应对ChatGPT带来的冲击给财务人员的建议总结 ✍创作者&#xff1a;全栈弄潮儿 &#x1f3e1; 个人主页&#xff1a; 全栈弄潮儿的个人主页 &#x1f3d9;️ 个人社区&#xff0c;欢迎你的加入&#xff1a;全栈弄潮儿的个人社…

Java“牵手”根据关键词搜索(分类搜索)拼多多商品列表页面数据获取方法,拼多多API实现批量商品数据抓取示例

拼多多商城是一个网上购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取拼多多商品列表和商品详情页面数据&#xff0c;您可以通过开放平台的接口或者直接访问拼多多商城的网页来获取商品列表和详情信息。以下是两种常用方…

No mapping found for HTTP request with URI

参考: 参考地址 说明 ssm老项目,接过来别人的项目 临时建了一个Controller方便测试用的,结果访问掉不通,报: No mapping found for HTTP request with URIxxxx 这样的错误 解决办法 看了下web,xml配置 在 webmvc-config.xml 配置文件里面添加了几行配置 说明: com.iph.h…

【JAVA程序设计】基于SpringBoot+vue的在线考试系统-以计算机网络为例,可自行录入题库-附下载地址

基于SpringBootvue的在线考试系统-以计算机网络为例&#xff0c;可自行录入题库 一、项目简介二、开发环境三、项目技术四、功能结构五、运行截图六、功能实现七、数据库设计八、源码获取 一、项目简介 随着信息技术的迅猛发展&#xff0c;教育行业正面临着巨大的变革和挑战。…

Apache-DBUtils

目录 封装方法 引出dbutils 案例 当关闭connection后&#xff0c;resultset结果集就无法使用了&#xff0c;这就使得resultset不利于数据的管理 封装方法 我们可以将结果集先存储在一个集合中&#xff0c;当connection关闭后&#xff0c;我们可以通过访问集合来访问结果集 …

Firefox(火狐),使用技巧汇总,问题处理

本文目的 说明火狐如何安装在C盘之外的盘&#xff0c;即定制安装路径。如何将同步功能切换到本地服务上。默认是国际服务器。安装在C盘之后如何解决&#xff0c;之前安装的扩展无法自动同步的问题。顺带讲解一下&#xff0c;火狐的一些比较好用的扩展。 安装路径定制 火狐目前…

系统架构设计师之缓存技术:Redis持久化的两种方式-RDB和AOF

系统架构设计师之缓存技术&#xff1a;Redis持久化的两种方式-RDB和AOF

期权分仓平台开户有什么优势?

期权分仓平台开户有什么优势&#xff1f;这最大的优势可以说零门槛开通上证50ETF期权和创业板ETF期权账户了&#xff0c;毕竟券商的门槛50万摆在那里&#xff0c;对于市场散户来说是遥望不可及的&#xff0c;只能选择第三方期权分仓平台来实现可以做期权交易的梦想。本文来自&a…

C语言:选择+编程(每日一练Day6)

目录 ​编辑选择题&#xff1a; 题一&#xff1a; 题二&#xff1a; 题三&#xff1a; 题四&#xff1a; 题五&#xff1a; 编程题&#xff1a; 题一&#xff1a;至少是其他数字两倍的最大数 思路一&#xff1a; 思路二&#xff1a; 题二&#xff1a;两个数组的交集…

docker之DockerFile与网络

目录 DockerFile 构建步骤 基础知识 指令 实战&#xff1a;构建自己的centos 第一步&#xff1a;编写dockerfile文件 第二步&#xff1a;构建镜像文件 docker网络 原理 功能 网络模式 host模式 container模式 none模式 bridge模式 DockerFile dockerfile 是用来…

交叉编译工具链

一、交叉编译 1. 编译原理 机器码&#xff08;二进制&#xff09;是处理器能直接识别的语言&#xff0c;不同的机器码代表不同的运算指令&#xff0c;处理器能够识别哪些机器码是由处理器的硬件设计所决定的&#xff0c;不同的处理器机器码不同&#xff0c;所以机器码不可移植…

Linux 进程间通信(IPC)

文章目录 进程间通信介绍进程间通信的概念进程间通信的目的进程间通信的本质理解进程间通信分类 管道匿名管道匿名管道的原理 pipe函数管道的特点 命名管道命名管道的原理使用相关命令创建命名管道使用命名管道实现server端和client端通信 system V共享内存共享内存通信的基本原…

算法基础(1):排序和查找算法

1、排序算法 1.1、堆排序(大顶堆)-重点&#xff1a; 参考文章&#xff1a;堆排序1、堆排序二 前置知识&#xff1a; 大顶堆&#xff1a;完全二叉树&#xff0c;且父节点大于左右儿子&#xff0c;左右子树又是大顶堆&#xff0c;依赖数组来实现(vector)第一个节点的父节点&…

【Rust】Rust学习 第十六章无畏并发

安全且高效的处理并发编程是 Rust 的另一个主要目标。并发编程&#xff08;Concurrent programming&#xff09;&#xff0c;代表程序的不同部分相互独立的执行&#xff0c;而 并行编程&#xff08;parallel programming&#xff09;代表程序不同部分于同时执行&#xff0c;这两…