先简介一下nodejs和NPM。Nodejs是2009年末Ryan Dahl在柏林的JavaScript大会上宣布的一项新技术,这项技术是关于在服务器端运行JavaScript的(是对JavaScript只能在浏览器端运行的一种颠覆)。Nodejs是一个基于Chrome V8引擎的JavaScript运行环境,而NPM则是用Nodejs开发的JavaScript包管理工具(作为Nodejs的一个扩展模块)。
有了Nodejs,无需再将书写好的代码部署到独立安装的Web服务器中去运行(Nodejs此时轻蔑地看了一眼NetBeans)。
1 安装
1.1 下载和安装
在 https://nodejs.org 下载Windows版的msi安装包。有两种版本的(LTS和Current),LTS可以满足大多数用户需求的,Current版本则包含了更多的新特征;
安装过程相当简单,打开安装包一路next就行了,唯一需要注意的是要记住安装的目录,之后设置模块全局目录需要用到(如果以后使用时发现安装中遗漏了哪些功能也可以再次打开安装包进行修复,nodejs的设计理念是之一就是只维护少量的依赖,因此其编译和安装变得非常简单);
安装之后打开命令行输入node -v
和npm -v
验证安装结果,如果安装成功都会出现相应的版本号(现在安装nodejs就顺带安装了npm这个模块了);
安装结束后,在系统的环境变量PATH
中自动被添加了Nodejs的安装路径,亲测后发现,如果这个路径丢了或被改了,在终端输入node或npm,cmd就会像看傻子一样告诉你这俩东西”“不是内部或外部命令,也不是可运行的程序或批处理文件”。
1.2 什么是REPL?如何使用?
REPL(Read Eval Print Loop),交互式解译器,表示一个电脑的环境,类似于Windows终端(cmd
)或者Unix/Linux shell
,Node.js 的交互式解释器可以很好的调试 Javascript 代码;
只要在终端中输入node
并回车即可启动;
交互式解释器,可以执行以下任务:
- 读取 - 读取用户输入,解析输入了Javascript 数据结构并存储在内存中。
- 执行 - 执行输入的数据结构
- 打印 - 输出结果
- 循环 - 循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出。
下面是两个常用的REPL命令:
Ctrl + C + C
或Ctrl + D
- 退出REPL(以前不知道每次都要重启cmd).help
- 列出使用命令
1.3 npm 外部模块的安装和删除
使用 npm 命令,可以安装、删除外部的模块( https://www.npmjs.com/ )
安装命令:
1 | npm i xxx # 等同于 npm install xxx |
删除命令(怎么安装的就怎么删除):
1 | npm uninstall xxx |
安装时如果下载速度太慢,可以使用淘宝提供的镜像安装方式,其安装方法为:
1 | $npm install -g cnpm --registry=https://registry.npm.taobao.org |
使用方法与npm完全一致,唯一区别就是命令由npm
改为cnpm
1.4 设置全局目录
全局目录包含两部分:cache(缓存)和global(模块包),默认安放在C盘的User\Administrator下,可以通过命令npm config get cache
和npm config get prefix
查看当前cache目录和global目录。
为了方便管理,我们在nodejs的安装目录下新建两个文件夹:node_cache
、node_global
,然后在终端使用$ npm config set cache "{global_path}/node_cache"
和$ npm config set prefix "{global_path}/node_global"
命令设置全局目录。
设置完node_global
,来到环境变量,把Path
里面的.../AppData/Roaming/npm
改成node_global
的绝对路径。
设置完成后,安装和删除单个模块时在后方加上-g
就可以对该目录下的模块操作了。
2 部署网站
2.1 安装express模块
1 | npm install express -g |
2.2 创建服务入口
首先创建一个js文件
,在里面输入代码段:
1 | var express = require("express"); |
代码的意思是将文件夹 G:/MyWebs 作为静态目录部署在端口3333下。
static()
函数里面的字符串是网站的路径名listen()
函数里面是端口号
2.3 访问
然后就可以通过REPL打开js文件来部署服务器啦,部署在本地服务器上,域名为localhost
或者127.0.0.1
,在后面加上端口号就可以访问啦。
1 | https://localhost:3333/ |
3 获取本地IP地址
参考资料:
nodejs官方API的os.networkInterfaces()
iteye用户zhangyaochun的博客
在局域网内供他人访问,首先要获取自己的IP地址,除了传统的ipconfig命令手动获取添加外,我们有必要考虑如何让nodejs自动获取主机的IP地址。
这里借用nodejs自带的os
模块里面的os.networkInterfaces()
方法来获取本地连接接口,os就是operation system操作系统模块。
3.1 编写获取IPv4的函数
编写函数getLocalIPv4()
函数,返回当前主机在网络连接中的IPv4地址:
1 | //获取IPv4地址 |
3.2 函数思路解析
函数的思路如下:
- 首先我们用
os.networkInterfaces()
获取对象,这个对象具体是啥我也不知道(直接输出devName
的话是“无线网络连接”、“Loopback Pseudo-Interface 1”这种鬼东西,好像后者即使没有联网也可以获取,类似于主机对外接口之类的东西吧),所以用devName
对其进行遍历,然后通过devName
作为索引来反向访问获取到的东西(聪明); - 通过连接名获取连接后,类似于ipconfig得到的连接样式,一个连接下面有IPv4、IPv6等各种各样的连接,这时候就要遍历这些IPv4、IPv6……通过
family
这个关键字来判断,然后排除掉内部连接和本地连接后,能进入if条件句的就是货真价实的IPv4了。
3.3 官方API对networkInterfaces()的解释
最后我们明确一下os.networkInterfaces()
获取到的究竟是个什么东西(前方大量抄袭!),官方API告诉我们,获取到的是一个对象(Object),其数据结构如下: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{
lo: [
{
address: '127.0.0.1',
netmask: '255.0.0.0',
family: 'IPv4',
mac: '00:00:00:00:00:00',
internal: true,
cidr: '127.0.0.1/8'
},
{
address: '::1',
netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
family: 'IPv6',
mac: '00:00:00:00:00:00',
internal: true,
cidr: '::1/128'
}
],
eth0: [
{
address: '192.168.1.108',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '01:02:03:0a:0b:0c',
internal: false,
cidr: '192.168.1.108/24'
},
{
address: 'fe80::a00:27ff:fe4e:66a1',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '01:02:03:0a:0b:0c',
internal: false,
cidr: 'fe80::a00:27ff:fe4e:66a1/64'
}
]
}
lo是内部地址,eth0是外部地址。
address
<string> The assigned IPv4 or IPv6 addressnetmask
<string> The IPv4 or IPv6 network maskfamily
<string> EitherIPv4
orIPv6
mac
<string> The MAC address of the network interfaceinternal
<boolean>true
if the network interface is a loopback or similar interface that is not remotely accessible; otherwisefalse
scopeid
<number> The numeric IPv6 scope ID (only specified whenfamily
isIPv6
)cidr
<string> The assigned IPv4 or IPv6 address with the routing prefix in CIDR notation. If thenetmask
is invalid, this property is set tonull