Node創建服務器

不學node的前端不是好流氓。

原生搭建簡單文件服務器

'use strict';

const fs = require('fs'),
    url = require('url'),
    path = require('path'),
    http = require('http');

const root = path.resolve(process.argv[2] || '.');
console.log('root' + root);

const server = http.createServer((request, response) => {
    const pathname = url.parse(request.url).pathname;
    const filepath = path.join(root, pathname);
    console.log(filepath);
    fs.stat(filepath, (err, stats) => {
        if (pathname === '/') {
            const indexPath = path.join(root, 'index.html');
            const defaultPath = path.join(root, 'default.html');
            fs.stat(indexPath, function (err, stat) {
                if (err) {
                    fs.stat(defaultPath, function (err, stat) {
                        if (err) {
                            console.log('can\'t find flie!');
                            response.writeHead(404, { 'Content-Type': 'text/html' });
                            response.end('<p>404 Not Found</p>')
                        } else {
                            console.log('file is exist!');
                            response.writeHead(200);
                            fs.createReadStream(defaultPath).pipe(response);
                        }
                    });
                } else {
                    console.log('file is exist!');
                    response.writeHead(200);
                    fs.createReadStream(indexPath).pipe(response);
                }
            });
        } else {
            if (!err && stats.isFile()) {
                console.log(`200 ${request.url}`);
                response.writeHead(200);
                fs.createReadStream(filepath).pipe(response);
            } else {
                console.log(`404 ${request.url}`);
                response.writeHead(404);
                response.end('404 Not Found');
            }
        }
    })

});

server.listen(8090);
console.log('server is running at http://127.0.0.1:8090/');

代碼分析

  • path.resolve([...paths])

path.resolve([...paths])#
Added in: v0.3.4
...paths: <String> A sequence of paths or path segments
Returns: <String>

The path.resolve() method resolves a sequence of paths or path segments into an absolute path.
The given sequence of paths is processed from right to left, with each subsequent path
prepended until an absolute path is constructed. For instance, given the sequence of path segments: /foo, /bar, baz,** calling path.resolve('/foo', '/bar', 'baz')** would <b>return /bar/baz </b>.
If after processing all given path segments an absolute path has not yet been generated, the current working directory is used.
The resulting path is normalized and trailing slashes are removed unless the path is resolved to the root directory.
Zero-length path segments are ignored.
If no path segments are passed, path.resolve() will return the absolute path of the current working directory.
For example:

path.resolve('/foo/bar', './baz');  // Returns: '/foo/bar/baz';
path.resolve('/foo/bar', '/tmp/file/'); // Returns: '/tmp/file';
path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
// if the current working directory is /home/myself/node;
// this returns '/home/myself/node/wwwroot/static_files/gif/image.gif'

A TypeError
is thrown if any of the arguments is not a string.
通過官方文檔可知 path.resolve()是用來解析合成絕對路徑的。

  • process.argv

Added in: v0.1.27
<Array>

The process.argv property returns an array containing the command line arguments passed when the Node.js process was launched. The first element will be process.execPath. See process.argv0 if access to the original value of argv[0] is needed. The second element will be the path to the JavaScript file being executed. The remaining elements will be any additional command line arguments.
For example, assuming the following script for process-args.js:

// print process.argv
process.argv.forEach((val, index) => {
  console.log(`${index}: ${val}`);
});

Launching the Node.js process as:

$ node process-2.js one two=three four

Would generate the output:

0: /usr/local/bin/node
1: /Users/mjr/work/node/process-2.js
2: one
3: two=three
4: four

總結: 這個是返回一個數組,第一個元素是node的執行文件目錄** 的路徑,第二個元素是js執行文件** 的路徑,剩下的元素可以是任何 命令行 的參數。

  • http.createServer([requestListener])#

Added in: v0.1.13
Returns: <http.Server>

Returns a new instance of http.Server.
The requestListener is a function which is automatically added to the 'request'
event.

  • server.listen([port][, hostname][, backlog][, callback])#

Added in: v0.1.90
port <Number>
hostname <String>
backlog <Number>
callback <Function>

Begin accepting connections on the specified port and hostname. If the hostname is omitted, the server will accept connections on any IPv6 address (::) when IPv6 is available, or any IPv4 address (0.0.0.0) otherwise. Omit the port argument, or use a port value of 0, to have the operating system assign a random port, which can be retrieved by using server.address().port after the 'listening' event has been emitted.
To listen to a unix socket, supply a filename instead of port and hostname.
backlog is the maximum length of the queue of pending connections. The actual length will be determined by your OS through sysctl settings such as tcp_max_syn_backlog and somaxconn on linux. The default value of this parameter is 511 (not 512). This function is asynchronous. callback will be added as a listener for the 'listening' event. See also net.Server.listen(port).
Note: The server.listen() method may be called multiple times. Each subsequent call will re-open the server using the provided options.
總結:這就是用來監聽端口的。奇怪的是如果端口為0或者沒傳,操作系統會隨機分配一個端口。

  • url.parse(urlString[, parseQueryString[, slashesDenoteHost]])#

Added in: v0.1.25
urlString <String> The URL string to parse.
parseQueryString <Boolean> If true, the query property will always be set to an object returned by the querystring module's parse() method. If false, the query property on the returned URL object will be an unparsed, undecoded string. Defaults to false.
slashesDenoteHost <Boolean> If true, the first token after the literal string // and preceding the next / will be interpreted as the host. For instance, given //foo/bar, the result would be {host: 'foo', pathname: '/bar'} rather than {pathname: '//foo/bar'}. Defaults to false.
The url.parse() method takes a URL string, parses it, and returns a URL object.
這個是用來解析URL字符串的,解析成 URLobject.

  • path.join([...paths])

Added in: v0.1.16
...paths <String> A sequence of path segments
Returns: <String>
For example:

path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')
// Returns: '/foo/bar/baz/asdf'

path.join('foo', {}, 'bar')
// throws TypeError: Arguments to path.join must be strings

總結:這是用來合成路徑的。

  • fs.stat(path, callback)

Added in: v0.0.2
path<String> | <Buffer>
callback <Function>
總結: 它返回一個Stat對象,能告訴我們文件或目錄的詳細信息

  • fs.createReadStream(path[, options])

總結: 打開創建一個可讀流。

  • fs.createWriteStream(path[, options])

總結: 打開創建一個可寫流。所有可以讀取數據的流都繼承自stream.Readable,所有可以寫入的流都繼承自stream.Writable。

  • pipe()

一個Readable流和一個Writable流串起來后,所有的數據自動從Readable流進入Writable流,這種操作叫pipe。

總結

這是原生node搭建的一個文件讀取服務器,基本讀取功能齊全,能做靜態網頁(簡單的官網等)的應用,代碼不是很難,稍微了解node的人都能很好的理解。重點是了解和熟悉node API 和 編程思想,為以后真正應用做基礎。 在命令行運行 ** node xxx.js(服務器js) /path/to/dir**,把 **/path/to/dir **改成你本地的一個有效的目錄。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容