Node.js基礎9:web 服務器1 請求與響應、路由

web 服務器

1介紹

在這裏插入圖片描述
客戶端服務器模塊

var http = require('http')
var onRequest = function (request,response) {
    //這個函數的參數分別是請求和響應,這兩個參數都實現了流,都是流的一個實例,可以像流一樣操作
    //request是瀏覽器發送過來的請求,response是要發給瀏覽器的響應
    console.log("Request Received");
    response.writeHead(200,{'Content-Type':'text/plain'})//寫入流,寫頭部信息,第一個參數是狀態碼.第二個參數代表要穿給瀏覽器的內容的類型
    //{'Content-Type':'text/plain'}代表告訴瀏覽器這是純文本內容,瀏覽器就理解了如何渲染他,如何讀取他
    // response.write('hello from out application')
    //response.end()
    response.end('hello from out application')//上面兩句或者這樣寫
}
var server = http.createServer(onRequest)
server.listen(3000,'127.0.0.1')//在3000端口監聽請求
console.log('Server started on localhost  port 3000')

然後node app.js開啓服務器
本地訪問127.0.0.1:3000

2 響應 json

響應json

var http = require('http');

var onRequest = function(request, response) {
    console.log('Request received');
    response.writeHead(200, { 'Content-Type': 'application/json' });
    // response.write('Hello from out application');
    var myObj = {
        name: "hfpp2012",
        job: "programmer",
        age: 27
    };
    response.end(JSON.stringify(myObj));
}

var server = http.createServer(onRequest);

server.listen(3000, '127.0.0.1');
console.log('Server started on localhost port 3000');

3響應HTML

app.js

var onRequest = function(request, response) {
    console.log('Request received');
    response.writeHead(200, { 'Content-Type': 'text/html' });
    var myReadStream = fs.createReadStream(__dirname + '/index.html', 'utf8');
    // response.write('Hello from out application');
    myReadStream.pipe(response);//可以直接用流和管道方便些
}

var server = http.createServer(onRequest);

server.listen(3000, '127.0.0.1');
console.log('Server started on localhost port 3000');

假設這是相同文件路徑下的index.html:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>xxx</title>
</head>

<body>
    hello wolrd
</body>

4用模塊化思想組織代碼

將服務器代碼單獨當成一個模塊分離出來
server.js

var http = require('http');
var fs = require('fs');

function startServer() {
    var onRequest = function(request, response) {
        console.log('Request received');
        response.writeHead(200, { 'Content-Type': 'text/html' });
        var myReadStream = fs.createReadStream(__dirname + '/index.html', 'utf8');
        // response.write('Hello from out application');
        myReadStream.pipe(response);
    }

    var server = http.createServer(onRequest);

    server.listen(3000, '127.0.0.1');
    console.log('Server started on localhost port 3000');
}

exports.startServer = startServer;

app.js

var server = require('./server');

server.startServer();

5路由

例如我們訪問一個網站,www.123.com/index
這個/index就是路由,訪問不同的頁面路由就不一樣,後臺處理的方式也不一樣,這樣用來請求不同的資源.
request.url獲取瀏覽器傳過來的路由信息,然後根據路由進行判斷
server.js

var http = require('http');
var fs = require('fs');

function startServer() {
    var onRequest = function(request, response) {
        console.log('Request received ' + request.url);//request.url獲取瀏覽器傳過來的路由信息,然後根據路由進行判斷
        if (request.url === '/' || request.url === '/home') {
            response.writeHead(200, { 'Content-Type': 'text/html' });
            fs.createReadStream(__dirname + '/index.html', 'utf8').pipe(response);
        } else if (request.url === '/review') {
            response.writeHead(200, { 'Content-Type': 'text/html' });
            fs.createReadStream(__dirname + '/review.html', 'utf8').pipe(response);
        } else if (request.url === '/api/v1/records') {
            response.writeHead(200, { 'Content-Type': 'application/json' });
            var jsonObj = {
                name: "hfpp2012"
            };
            response.end(JSON.stringify(jsonObj));
        } else {
            response.writeHead(404, { 'Content-Type': 'text/html' });
            fs.createReadStream(__dirname + '/404.html', 'utf8').pipe(response);
        }
    }

    var server = http.createServer(onRequest);

    server.listen(3000, '127.0.0.1');
    console.log('Server started on localhost port 3000');
}

exports.startServer = startServer;

review.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    review page
</body>

</html>

404.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    404 error page
</body>

</html>

6重構路由代碼

app.js

var server = require('./server');
var router = require('./router');
var handler = require('./handler');

var handle = {};
handle["/"] = handler.home;
handle['/home'] = handler.home;
handle['/review'] = handler.review;
handle['/api/v1/records'] = handler.api_records;

server.startServer(router.route, handle);

server.js

var http = require('http');
var fs = require('fs');

function startServer(route, handle) {
    var onRequest = function(request, response) {
        console.log('Request received ' + request.url);
        route(handle, request.url, response);
    }

    var server = http.createServer(onRequest);

    server.listen(3000, '127.0.0.1');
    console.log('Server started on localhost port 3000');
}

module.exports.startServer = startServer;

router.js

var fs = require('fs');

function route(handle, pathname, response) {
    console.log('Routing a request for ' + pathname);
    if (typeof handle[pathname] === 'function') {
        handle[pathname](response);
    } else {
        response.writeHead(200, { 'Content-Type': 'text/html' });
        fs.createReadStream(__dirname + '/404.html', 'utf8').pipe(response);
    }
}

module.exports.route = route;

handler.js

var fs = require('fs');

function home(response) {
    response.writeHead(200, { 'Content-Type': 'text/html' });
    fs.createReadStream(__dirname + '/index.html', 'utf8').pipe(response);
}

function review(response) {
    response.writeHead(200, { 'Content-Type': 'text/html' });
    fs.createReadStream(__dirname + '/review.html', 'utf8').pipe(response);
}

function api_records(response) {
    response.writeHead(200, { 'Content-Type': 'application/json' });
    var jsonObj = {
        name: "hfpp2012"
    };
    response.end(JSON.stringify(jsonObj));
}

module.exports = {
    home: home,
    review: review,
    api_records: api_records
}

解析:
將server router handle 分別分離,各自掌管不同的功能

if (request.url === '/' || request.url === '/home') {
            response.writeHead(200, { 'Content-Type': 'text/html' });
            fs.createReadStream(__dirname + '/index.html', 'utf8').pipe(response);
        } else if (request.url === '/review') {
            response.writeHead(200, { 'Content-Type': 'text/html' });
            fs.createReadStream(__dirname + '/review.html', 'utf8').pipe(response);
        } else if (request.url === '/api/v1/records') {
            response.writeHead(200, { 'Content-Type': 'application/json' });
            var jsonObj = {
                name: "hfpp2012"
            };
            response.end(JSON.stringify(jsonObj));
        } else {
            response.writeHead(404, { 'Content-Type': 'text/html' });
            fs.createReadStream(__dirname + '/404.html', 'utf8').pipe(response);
        }
    }

router相當於上面這段代碼的if()else(),起到:根據不同路徑,判斷該走哪條路的作用.
handle 根據不同的路,來執行不同的方法.相當於ifelse中{}內執行的代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章