教你快速搭建Node.Js服務(wù)器的方法教程
前言
Node.js 是一個(gè)事件驅(qū)動(dòng) I/O 服務(wù)端 JavaScript 環(huán)境,也可以理解為服務(wù)器端運(yùn)行的 JavaScript。JS 作為一門(mén)編程語(yǔ)言,是運(yùn)行在稱為 JS 運(yùn)行時(shí)的虛擬機(jī)中的,而在 I/O 功能上,JS 更多依賴于宿主環(huán)境。一般我們遇到的宿主環(huán)境主要是瀏覽器,Node.js 則是在服務(wù)器端運(yùn)行的高速 JavaScript 解釋器。
近期遇到一個(gè)小型網(wǎng)站需要建立一個(gè)簡(jiǎn)單的 Web 服務(wù)器,原本想用 SpringMVC 解決,無(wú)奈 Spring 的哲學(xué)博大精深,自己才疏學(xué)淺,不能快速出貨,因此決定用 Node.js 試試,這里就簡(jiǎn)單介紹下如何快速啟動(dòng)一個(gè)簡(jiǎn)單易用的 Web Server。這里我使用的開(kāi)發(fā)環(huán)境是基于 Ubuntu 14.04 的 Elementary OS。
1. 準(zhǔn)備工作
1.1 安裝 NodeJS 環(huán)境和 npm 模塊管理器
sudo apt-get install nodejs sudo apt-get install npm
npm 是一個(gè)優(yōu)秀的 Node 模塊管理器,在開(kāi)發(fā)中幫助我們解決很多第三方代碼庫(kù)的依賴管理事務(wù)。
1.2 設(shè)置 npm 代理
假如沒(méi)有提前做任何額外措施,那么必然當(dāng)你使用 npm 從網(wǎng)絡(luò)下載自己需要的 NodeJs 模塊時(shí),速度會(huì)非常慢,甚至?xí)虺瑫r(shí)而失敗,具體原因不多講,推薦使用淘寶的 npm 鏡像,問(wèn)題會(huì)得到解決。
- 打開(kāi) ~/.npmrc 文件
- 輸入
registry = https://registry.npm.taobao.org - 保存退出
注意如果你曾設(shè)置過(guò)全局穿墻但是 npm 依然速度很慢,可以試試在 ~/.npmrc 文件中繼續(xù)添加
- proxy=false
2. 用 Express Generator 搭建開(kāi)發(fā)環(huán)境
Express 是目前最流行的基于 Node.js 的 Web 開(kāi)發(fā)框架,可以快速地搭建一個(gè)完整功能的網(wǎng)站。
Express Generator 是 Express 的應(yīng)用程序生成器工具,使用它可以快速建立完整的項(xiàng)目文件目錄。
2.1 安裝 Express Generator
$ npm install express-generator -g
2.2 建立 Express 應(yīng)用程序
express --view=pug NodeApp
這里 view 參數(shù)是用來(lái)預(yù)設(shè)開(kāi)發(fā)中使用的模板引擎的。更多參數(shù)如下
express -h Usage: express [options] [dir] Options: -h, --help output usage information --version output the version number -e, --ejs add ejs engine support --pug add pug engine support --hbs add handlebars engine support -H, --hogan add hogan.js engine support -v, --view <engine> add view <engine> support (ejs|hbs|hjs|jade|pug|twig|vash) (defaults to jade) -c, --css <engine> add stylesheet <engine> support (less|stylus|compass|sass) (defaults to plain css) --git add .gitignore -f, --force force on non-empty directory
2.3 解決模塊依賴
進(jìn)入剛剛建立的 NodeApp 文件夾,可以看到里面有一個(gè) package.json 文件,它定義了這個(gè)項(xiàng)目所需要的各種模塊,以及項(xiàng)目的配置信息(比如名稱、版本、許可證等元數(shù)據(jù)),npm可以依據(jù)它來(lái)管理項(xiàng)目模塊。
打開(kāi) package.json 可以看到里面的內(nèi)容如下
{
"name": "NodeApp",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"body-parser": "~1.16.0",
"cookie-parser": "~1.4.3",
"debug": "~2.6.0",
"express": "~4.14.1",
"morgan": "~1.7.0",
"pug": "~2.0.0-beta10",
"serve-favicon": "~2.3.2"
}
}
現(xiàn)在在終端執(zhí)行 npm 命令解決模塊依賴,npm 會(huì)按照 package.json 文件的內(nèi)容下載相應(yīng)模塊,當(dāng)然,如果沒(méi)有設(shè)置穿墻措施這一步是無(wú)法執(zhí)行的
npm intsall
3. 初次啟動(dòng)服務(wù)器
基本上該有的配置和基本的邏輯代碼 Express Generator 都幫我們做好了,那么我們其實(shí)已經(jīng)可以用一行命令啟動(dòng)服務(wù)器了。
執(zhí)行以下命令
npm start
訪問(wèn) localhost:3000 即可看到 Express 歡迎頁(yè)面了。
4. 設(shè)置訪問(wèn)地址
可以看到在之前建立的文件目錄下還有一個(gè) app.js 文件,其實(shí)它就充當(dāng)了一個(gè)項(xiàng)目中的main函數(shù)的角色,里面使用了很多 Express 中間件和 Express 語(yǔ)法,這里不一一敘述。
在實(shí)際生產(chǎn)環(huán)境中,我們需要自己設(shè)定外部訪問(wèn)端口,比如通過(guò) Http 的 80 端口訪問(wèn)我們的服務(wù)器,那么就可以在app.js文件的 "module.exports = app;" 語(yǔ)句前加上如下代碼
var server = app.listen(80, "0.0.0.0", function () {
console.log("服務(wù)器IP地址:" + ip.address());
var host = server.address().address;
var port = server.address().port;
console.log("應(yīng)用已啟動(dòng),訪問(wèn)地址為 http://%s:%s", host, port)
});
這里簡(jiǎn)單解釋下,80 意味著我們的服務(wù)器程序?qū)⒈O(jiān)聽(tīng)本機(jī)的80端口,0.0.0.0 意味著本地和外部訪問(wèn)請(qǐng)求都將由我們的服務(wù)器程序進(jìn)行處理。
同時(shí)啟動(dòng)了服務(wù)器后我們?cè)诮K端也可以看到當(dāng)前主機(jī)的IP地址以及服務(wù)器程序接受的訪問(wèn)地址。
5. 設(shè)置 index 頁(yè)面內(nèi)容
到這里為止,我們?cè)L問(wèn) localhost 地址會(huì)看到 Express 默認(rèn)的歡迎頁(yè)面,那么如何返回一個(gè)我們自己的頁(yè)面呢。比如我們現(xiàn)在有一個(gè) index.html 頁(yè)面,我們需要在用戶訪問(wèn) localhost 時(shí)返回這個(gè) html 頁(yè)面,暫時(shí)不考慮靜態(tài)文件的問(wèn)題。
可以進(jìn)入 app.js 文件,它現(xiàn)在應(yīng)該長(zhǎng)這樣,
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
var server = app.listen(80, "0.0.0.0", function () {
console.log("服務(wù)器IP地址:" + ip.address());
var host = server.address().address;
var port = server.address().port;
console.log("應(yīng)用已啟動(dòng),訪問(wèn)地址為 http://%s:%s", host, port)
});
module.exports = app;
其中有一句是這樣的
app.use('/', index);
它的含義是當(dāng)服務(wù)器程序捕獲訪問(wèn)路徑為 "/" 的請(qǐng)求時(shí),由 index 中間件進(jìn)行相應(yīng)處理。
在這里對(duì)于 Express 中間件網(wǎng)上有很好的描述
簡(jiǎn)單說(shuō),中間件(middleware)就是處理 HTTP 請(qǐng)求的函數(shù)。它最大的特點(diǎn)就是,一個(gè)中間件處理完,再傳遞給下一個(gè)中間件。App 實(shí)例在運(yùn)行過(guò)程中,會(huì)調(diào)用一系列的中間件。 每個(gè)中間件可以從 App 實(shí)例,接收三個(gè)參數(shù),依次為 request 對(duì)象(代表 HTTP 請(qǐng)求)、response 對(duì)象(代表 HTTP 回應(yīng)),next 回調(diào)函數(shù)(代表下一個(gè)中間件)。每個(gè)中間件都可以對(duì) HTTP 請(qǐng)求(request 對(duì)象)進(jìn)行加工,并且決定是否調(diào)用next 方法,將 request 對(duì)象再傳給下一個(gè)中間件。
那么 index 中間件從何而來(lái)呢?
var index = require('./routes/index');
所以我們可以去 routes 文件夾下查看 index 文件,它應(yīng)該長(zhǎng)這樣
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { title: 'Express' });
});
module.exports = router;
從代碼注釋可以看出,這里就是負(fù)責(zé)返回前面提到的 Express 歡迎頁(yè)面的邏輯代碼,當(dāng)然它使用到了模板引擎的知識(shí),我們不具體介紹,直接簡(jiǎn)單粗暴地實(shí)現(xiàn)我們的需求吧。
首先我們把 index.html 頁(yè)面保存到文件目錄下的 public/html 文件夾下(沒(méi)有就自己創(chuàng)建),然后我們?cè)?routes/index 文件中返回這個(gè) html 頁(yè)面,在這里我們將使用到文件讀寫(xiě)方法。
var path = require('path');
res.sendFile(path.resolve('public/html/index.html'));
path 變量是 Express 中的變量,path.resolve 方法可以將傳入的相對(duì)地址轉(zhuǎn)換為絕對(duì)地址,這里面涉及到關(guān)于 NodeJs 文件路徑的知識(shí),不做具體介紹。
res 變量代表著服務(wù)器對(duì)于此次請(qǐng)求的返回對(duì)象,那么在這里相當(dāng)于我們向客戶端返回的是存放在 public/html/index.html 文件。
重啟程序,訪問(wèn) localhost,就可以看到 index.html 了。
6. 設(shè)置靜態(tài)文件路徑
對(duì)于 JS 和 CSS 這樣的靜態(tài)文件,在 Express 中都統(tǒng)一放置在 public 文件夾下,Express 遇到對(duì)靜態(tài)文件的請(qǐng)求將會(huì)從 pulic 下讀取并返回相應(yīng)文件。
而設(shè)置這一路徑的語(yǔ)句其實(shí)也在 app.js 中
app.use(express.static(path.join(__dirname, 'public')));
因此如果項(xiàng)目需要,也可以自行修改這一路經(jīng)。
7. 后臺(tái)運(yùn)行服務(wù)器
在之前我們終端運(yùn)行 npm start 的時(shí)候,應(yīng)該可以看到所有訪問(wèn)打印的日志語(yǔ)句都在終端顯示了,這時(shí)如果我們關(guān)閉終端,程序也將相應(yīng)停止,那么如何在后臺(tái)運(yùn)行我們的服務(wù)器程序,并將打印的日志語(yǔ)句都寫(xiě)入到專(zhuān)門(mén)的日志文件呢,這里需要用到 Linux 的 nohup 命令和重定向符。
npm start 1> log 2> error
> 是linux下的重定向符。> 將會(huì)重新寫(xiě)入目標(biāo)文件,即不保存目標(biāo)文件的原始內(nèi)容,如果使用 >> 則會(huì)在目標(biāo)文件后面附加內(nèi)容。
在 Linux 中,一個(gè)程序可以在幾個(gè)編號(hào)的文件流中的任一個(gè)上產(chǎn)生輸出。然而我們必須把這些文件流的前三個(gè)看作標(biāo)準(zhǔn)輸入,輸出和錯(cuò)誤,shell 內(nèi)部參考它們?yōu)槲募枋龇?0,1 和 2。因此這個(gè)語(yǔ)句的意思就是將標(biāo)準(zhǔn)輸出重定向到當(dāng)前目錄下的 log 文件中,將錯(cuò)誤輸出重定向到當(dāng)前目錄下的 error 文件中。
但是這樣只解決了輸出信息的轉(zhuǎn)移輸出問(wèn)題,程序依然是在終端下運(yùn)行的??梢允褂?Linux 下的 nohup 命令實(shí)現(xiàn)這一目的,使用如下
nohup npm start 1> log 2> error &
不要忘記最末位的 & 符號(hào)。
在后臺(tái)運(yùn)行作業(yè)時(shí)要當(dāng)心:需要用戶交互的命令不要放在后臺(tái)執(zhí)行,因?yàn)檫@樣你的機(jī)器就會(huì)在那里傻等。不過(guò),作業(yè)在后臺(tái)運(yùn)行一樣會(huì)將結(jié)果輸出到屏幕上,干擾你的工作,因此需要重定向符的幫助。
后續(xù)
現(xiàn)在一個(gè)簡(jiǎn)單的 Web 服務(wù)器就搭建完成了,這只是一個(gè) Web 服務(wù)器最開(kāi)始的一段路,后面的開(kāi)發(fā)則需要對(duì) NodeJs 和 Express 的深入學(xué)習(xí)和使用。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- Node.js實(shí)戰(zhàn) 建立簡(jiǎn)單的Web服務(wù)器
- 輕松創(chuàng)建nodejs服務(wù)器(1):一個(gè)簡(jiǎn)單nodejs服務(wù)器例子
- 輕松創(chuàng)建nodejs服務(wù)器(10):處理上傳圖片
- 輕松創(chuàng)建nodejs服務(wù)器(10):處理POST請(qǐng)求
- 輕松創(chuàng)建nodejs服務(wù)器(4):路由
- 輕松創(chuàng)建nodejs服務(wù)器(3):代碼模塊化
- nodejs創(chuàng)建web服務(wù)器之hello world程序
- Nodejs如何搭建Web服務(wù)器
- Nodejs 搭建簡(jiǎn)單的Web服務(wù)器詳解及實(shí)例
- iPhone手機(jī)上搭建nodejs服務(wù)器步驟方法
相關(guān)文章
webpack創(chuàng)建項(xiàng)目并打包的詳細(xì)流程記錄
webpack在前端工程領(lǐng)域起到了中流砥柱的作用,理解它的內(nèi)部實(shí)現(xiàn)機(jī)制會(huì)對(duì)你的工程建設(shè)提供很大的幫助(不論是定制功能還是優(yōu)化打包),下面這篇文章主要給大家介紹了關(guān)于webpack創(chuàng)建項(xiàng)目并打包的詳細(xì)流程,需要的朋友可以參考下2023-03-03
了不起的node.js讀書(shū)筆記之node的學(xué)習(xí)總結(jié)
這篇文章主要介紹了了不起的node.js讀書(shū)筆記之node的學(xué)習(xí)總結(jié),需要的朋友可以參考下2014-12-12
nodejs實(shí)現(xiàn)套接字服務(wù)功能詳解
這篇文章主要介紹了nodejs實(shí)現(xiàn)套接字服務(wù)功能,簡(jiǎn)單描述了套接字的概念、功能,并結(jié)合實(shí)例形式分析了nodejs使用socket對(duì)象創(chuàng)建及使用套接字進(jìn)行數(shù)據(jù)傳輸相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2018-06-06
node.js平臺(tái)下利用cookie實(shí)現(xiàn)記住密碼登陸(Express+Ejs+Mysql)
這篇文章主要介紹了node.js平臺(tái)下利用cookie實(shí)現(xiàn)記住密碼登陸(Express+Ejs+Mysql),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04
Node中使用http-proxy-middleware實(shí)現(xiàn)代理跨域的方法步驟
本文主要介紹了Node中使用http-proxy-middleware實(shí)現(xiàn)代理跨域的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11
讓nodeJS支持ES6的詞法----babel的安裝和使用方法
這篇文章主要介紹了讓nodeJS支持ES6的詞法----babel的安裝和使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07

