0
点赞
收藏
分享

微信扫一扫

【Web开发】Node.js实现Web服务器

文章目录

在这里插入图片描述

1、简介

官网地址:https://nodejs.org/

Node.js 是一个开源和跨平台的 JavaScript 运行时环境。它是几乎任何类型的项目的流行工具!

Node.js 在浏览器之外运行 Google Chrome 的核心 V8 JavaScript 引擎。这使得 Node.js 非常高效。

Node.js 应用程序在单个进程中运行,无需为每个请求创建新线程。Node.js 在其标准库中提供了一组异步 I/O 原语,可防止 JavaScript 代码阻塞,通常,Node.js 中的库是使用非阻塞范例编写的,使阻塞行为成为例外而不是常态。

当 Node.js 执行 I/O 操作时,例如从网络读取、访问数据库或文件系统,而不是阻塞线程并浪费 CPU 周期等待,Node.js 将在响应返回时恢复操作。

这允许 Node.js 处理与单个服务器的数千个并发连接,而​​不会引入管理线程并发的负担,这可能是错误的重要来源。

Node.js 有一个独特的优势,因为数百万为浏览器编写 JavaScript 的前端开发人员现在能够编写除了客户端代码之外的服务器端代码,而无需学习完全不同的语言。

在 Node.js 中,可以毫无问题地使用新的 ECMAScript 标准,因为您不必等待所有用户更新他们的浏览器 - 您可以通过更改 Node.js 版本来决定使用哪个 ECMAScript 版本,您还可以通过运行带有标志的 Node.js 来启用特定的实验功能。
在这里插入图片描述

2、下载和安装

https://nodejs.org/en/download/
在这里插入图片描述

当前官网最新版本:
Latest LTS Version: 16.14.2 (includes npm 8.5.0)

查看node版本:

node -v

在这里插入图片描述

查看npm版本:

npm -v

在这里插入图片描述

3、NPM使用

npm 是 Node.js 标准的软件包管理器。
它起初是作为下载和管理 Node.js 包依赖的方式,但其现在也已成为前端 JavaScript 中使用的工具。
Yarn 是 npm 的一个替代选择。

3.1 下载

npm 可以管理项目依赖的下载。

  • 安装所有依赖
    如果项目具有 package.json 文件,则通过运行:
npm install

它会在 node_modules 文件夹(如果尚不存在则会创建)中安装项目所需的所有东西。

  • 安装单个软件包
npm install <package-name>

通常会在此命令中看到更多标志:
–save 安装并添加条目到 package.json 文件的 dependencies。
–save-dev 安装并添加条目到 package.json 文件的 devDependencies。
区别主要是,devDependencies 通常是开发的工具(例如测试的库),而 dependencies 则是与生产环境中的应用程序相关。

  • 更新软件包

检查所有软件包是否有满足版本限制的更新版本。

npm update

也可以指定单个软件包进行更新:

npm update <package-name>

3.2 版本控制

除了简单的下载外,npm 还可以管理版本控制,因此可以指定软件包的任何特定版本,或者要求版本高于或低于所需版本。很多时候,一个库仅与另一个库的主版本兼容。

3.3 运行任务

package.json 文件支持一种用于指定命令行任务(可通过使用以下方式运行)的格式:

npm run <task-name>

比如package.json可以写成如下内容:

{
  "scripts": {
    "start-dev": "node lib/server-development",
    "start": "node lib/server-production"
  },
}

{
  "scripts": {
    "watch": "webpack --watch --progress --colors --config webpack.conf.js",
    "dev": "webpack --progress --colors --config webpack.conf.js",
    "prod": "NODE_ENV=production webpack -p --config webpack.conf.js",
  },
}

因此可以运行如下,而不是输入那些容易忘记或输入错误的长命令:

$ npm run watch
$ npm run dev
$ npm run prod

3.4 软件包安装位置

当使用 npm 安装软件包时,可以执行两种安装类型:

  • 本地安装
  • 全局安装

默认情况下,当输入 npm install 命令时,例如:

npm install vue

软件包会被安装到当前文件树中的 node_modules 子文件夹下。
在这种情况下,npm 还会在当前文件夹中存在的 package.json 文件的 dependencies 属性中添加 vue条目。
使用 -g 标志可以执行全局安装:

npm install -g vue

在这种情况下,npm 不会将软件包安装到本地文件夹下,而是使用全局的位置。
npm root -g 命令会告知其在计算机上的确切位置。
当添加了 -D 或 --save-dev 标志时,则会将其安装为开发依赖项(会被添加到 devDependencies 列表)。

npm root -g

在这里插入图片描述
也可以通过如下代码查看全局安装路径:

npm config get prefix

在这里插入图片描述

3.5 查看 npm 包安装的版本

若要查看所有已安装的 npm 软件包(包括它们的依赖包)的最新版本,则:

npm list

也可以打开 package-lock.json 文件,但这需要进行一些视觉扫描。
npm list -g 也一样,但适用于全局安装的软件包。

npm list -g
npm list -g --depth 0

在这里插入图片描述
如果要查看软件包在 npm 仓库上最新的可用版本,则运行 npm view [package_name] version:

npm view vue version

在这里插入图片描述

3.6 安装 npm 包的旧版本

可以使用 @ 语法来安装 npm 软件包的旧版本:

npm install <package>@<version>
npm install cowsay
npm install cowsay@1.2.0
npm install -g webpack@4.16.4

可能还有需要列出软件包所有的以前的版本。 可以使用 npm view versions:
在这里插入图片描述

3.7 卸载 npm 软件包

若要卸载之前在本地安装(在 node_modules 文件夹使用 npm install )的软件包,则从项目的根文件夹(包含 node_modules 文件夹的文件夹)中运行:

npm uninstall <package-name>

如果使用 -S 或 --save 标志,则此操作还会移除 package.json 文件中的引用。
如果程序包是开发依赖项(列出在 package.json 文件的 devDependencies 中),则必须使用 -D 或 --save-dev 标志从文件中移除:

npm uninstall -S <package-name>
npm uninstall -D <package-name>

如果该软件包是全局安装的,则需要添加 -g 或 --global 标志:

npm uninstall -g <package-name>
npm uninstall -g vue

3.8 npm 淘宝镜像的安装

由于node下载第三方依赖包是从国外服务器下载,但是下载的速度是非常的缓慢且有可能会出现异常。所以为了提高效率,我们还是把npm的镜像源替换成淘宝的镜像源。

只在当前工程中使用阿里定制的cnpm命令行工具,代码如下:

$ npm install cnpm --registry=https://registry.npm.taobao.org

在这里插入图片描述

使用阿里定制的cnpm命令行工具代替全局默认的npm,输入以下代码

$ npm install -g cnpm --registry=https://registry.npm.taobao.org

在这里插入图片描述

检测是否安装成功:

$ cnpm -v

在这里插入图片描述

安装成功之后,以后安装依赖包的方式和npm的是一样的,只是npm的命令换成是cnpm就可以了。

假如你已经习惯了使用npm的安装方式的,不想去下载阿里的cnpm命令工具的话,很简单,我们直接将node的仓库地址换成淘宝仓库地址。

# 单次使用
$ npm install --registry=https://registry.npm.taobao.org

# 永久使用
## 直接命令行的设置
$ npm config set registry https://registry.npm.taobao.org
## 手动修改设置
1.打开.npmrc文件(C:\Program Files\nodejs\node_modules\npm\npmrc,没有的话可以使用git命令行建一个( touch .npmrc),用cmd命令建会报错)
2.增加 registry =https://registry.npm.taobao.org  即可。

## 配置后可通过下面方式来验证是否成功
$ npm config get registry

## 如果想还原npm仓库地址的话
$ npm config set registry https://registry.npmjs.org/

在这里插入图片描述

4、基于http模块

HTTP 核心模块是 Node.js 网络的关键模块。

// http://nodejs.cn/learn/the-nodejs-http-module
const http = require('http')

4.1 最简单示例

  • server1.js:
var http = require("http");

http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}).listen(3000);

运行结果如下:
在这里插入图片描述

4.2 输出字符串

https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/

  • server2.js:
const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

运行结果如下:
在这里插入图片描述

4.3 输出网页文件

  • server3.js:
var http = require('http');
var fs = require('fs');
var url = require('url');
const path = require('path');

// 创建服务器
http.createServer(function (req, res) {
    // 解析请求,包括文件名
    var pathname = url.parse(req.url).pathname;
   //获取node.exe的绝对路径
   console.log(process.execPath);//D:\nodejs\node.exe

    //当前文件(即server.js)的绝对路径
    console.log(__filename);//D:\nodeTest\node_path\lib\server.js

   //存放当前文件(即server.js)文件夹的绝对路径
   console.log(__dirname);//D:\nodeTest\node_path\lib

   //从所传入的文件路径(相对或绝对)中获取存放传入文件的文件夹的相对或绝对路径 
   //(例如 传入 public/home.html 则返回的是public)
   console.log(path.dirname(__filename));//D:\nodeTest\node_path\lib

   //执行当前脚本(即server.js)的位置 (例如 在根目录下执行 node ./xxx/xxx/a.js 则返回的是根目录地址 )
   console.log(process.cwd());//D:\nodeTest\node_path\lib

    // 输出请求的文件名
    console.log("Request for " + pathname + " received.");
    if (pathname == "/") {
        fs.stat('/index.html', function (err, stat) {
            if (stat && stat.isFile()) {
                console.log('index.html existed.');
            } else {
                console.log('index.html not existed.');
            }
        });

        fs.readFile("index.html", function (err, data) {
            if (err) {
                res.statusCode = 200;
                res.setHeader('Content-Type', 'text/plain');
                res.end('Hello World');
            } else {
                res.writeHead(200, {
                    "Content-Type": "text/html;charset=UTF-8"
                });
                res.end(data);
            }
        });
    } else if (pathname.indexOf(".jpg") != -1 || pathname.indexOf(".png") != -1) {
        
        fs.readFile(__dirname + pathname, 'binary', function (err, data) {
            if (err) {
                console.log(err);
            } else {
                res.writeHead(200, {'Content-type':'image/jpeg'});
                res.write(data, 'binary');
                res.end();
            }
        });
    } else {
        // 从文件系统中读取请求的文件内容
        fs.readFile(__dirname + pathname, function (err, data) {
            if (err) {
                console.log(err);
                // HTTP 状态码: 404 : NOT FOUND
                // Content Type: text/html
                res.writeHead(404, {
                    'Content-Type': 'text/html'
                });
            } else {
                // HTTP 状态码: 200 : OK
                // Content Type: text/html
                res.writeHead(200, {
                    'Content-Type': 'text/html;charset=utf-8'
                });

                // 响应文件内容
                res.write(data.toString());
            }
            //  发送响应数据
            res.end();
        });
    }

}).listen(3000);

// 控制台会输出以下信息
console.log('Server running at http://127.0.0.1:3000/');
  • web服务器运行:

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

  • 浏览器客户端访问:
    在这里插入图片描述
  1. 输出字符串
    在这里插入图片描述
  2. 输出文本文件
    在这里插入图片描述
  3. 输出图片文件:
    在这里插入图片描述
  4. 输出网页文件:
    在这里插入图片描述

后记

举报

相关推荐

0 条评论