NodeJS處理HTTP響應與請求


@


一、系統模塊http -- 創建web服務端

http 模塊 是 Node.js 官方提供的、用來 創建 web 服務器 的模塊。

不需要使用 IIS、Apache 等這些第三方 web 服務器軟件,可直接通過 http 模塊提供的 http.createServer() 方法,就能方便的把一台普通的電腦,變成一台最基本的 Web 服務器,從而對外提供 Web 資源服務。

//app.js
// 1. 引用http系統模塊
const http = require('http');

// 2. http.createSercer(): 創建web服務器
const server = http.createServer();

// 3. 為服務器實例綁定 request 事件
server.on('request', (req, res) => {
	console.log('someone visit my web server')
})

// 4. 啟動服務器
// Server.listen(端口號, callback):監聽端口,網站服務器必須監聽端口,否者無法向外服務
server.listen(3000, () => {
	console.log('服務器已啟動,監聽3000端口,請訪問 localhost:3000')
});

之后通過命令行的方式開啟服務器端node app.js


二、NodeJS服務端接收並處理客戶端請求

server.on('requeset', function(req, res){})

在服務器創建成功后,調用通過 on() 為服務器注冊的 request 事件 並綁定處理函數,函數中可傳入兩個參數

其中參數 req表示 客戶端請求相關的數據或屬性

另一個參數 res 表示 服務器響應相關的數據或屬性

舉例:

// 通過 on 方式 添加 請求事件 request, 后面函數為事件綁定函數, 當客戶端發送請求到服務端就執行該函數;
/*
req : 代表請求對象,該對象保存了請求相關的信息
res : 代表響應對象, 對客戶端的請求進行響應
*/
server.on('request', (req, res) => {

	//req.method : 獲取請求方式
	console.log(req.method);
	
	//req.url : 獲取請求地址
	console.log(req.url);
	
	//req.headers : 獲取請求報文
	console.log(req.headers);

	/* 
	res.writedHead(parms1, parms2): 設置響應報文
		parms1: 設置響應頭中的 http狀態碼, Number
		parms2: 設置響應頭中的頭部字段, object
	注意:res.writedHead() 需要在 res.end() 之前調用才有效
	*/ 
	res.writeHead(200, {
		//指定響應頭中Content-Type字段值,值為響應內容類型,指定字符編碼以免亂碼
		'Content-Type': 'text/html;charset=utf8'
	});
	
	//res.end() : 根據請求響應客戶端
	res.end('這是服務端響應給客戶端頁面的內容');
});

在這里插入圖片描述


③ 解決中文亂碼問題

當調用 res.end() 方法,向客戶端發送中文內容的時候,會出現亂碼問題,此時,需要手動設置內容的編碼格式:

server.on('request', (req, res) => {
	// 響應內容包含中文
	const str = `您的請求的 url 地址是 ${req.url}, 請求的 method 類型是  ${req.method}`;
	// 為了防止顯示中文亂碼問題,需要設置響應頭 Content-Type 的值為 text/html; charset=utf-8
	res.setHeader('Content-Type', 'text/html; charset=utf-8')
	// 把包含中文的內容,響應給客戶端
	res.end(str)
})

三、NodeJS 服務端處理請求參數

1. 系統模塊url -- 處理GET請求參數

get請求參數一般放置在瀏覽器地址欄中,例如:http://localhost:3000/?name=zhangsan&age=20

  • 參數獲取需要借助系統模塊url,url模塊用來處理url地址
  • 通過 url.parse() 來解析req.url地址,並更具第二參數判斷是否以對象的方式飯返回
//eg :在服務端接收到客戶端請求中的參數
const http = require('http');
// 導入url系統模塊 用於處理url地址
const url = require('url');
const app = http.createServer();
app.on('request', (req, res) => {
	console.log(req.url);
	console.log(url.parse(req.url, true));
	// 將url路徑的各個部分解析出來並返回對象
	// true 代表將參數解析為對象格式
	let {query, pathname} = url.parse(req.url, true);
		console.log(query);
		console.log(pathname)
	});
app.listen(1234);

在這里插入圖片描述



2. 系統模塊querystring -- 處理POST請求參數

  • 參數被放置在請求頭中發送到服務端
    在這里插入圖片描述

  • 使用 querystring系統模塊 將post參數轉換為 對象格式

  • 獲取POST參數需要使用 data事件和 end事件

如果post參數數據量比較大,無法一次性發送完畢,則客戶端會把數據切割后,分批發送到服務器。所以 data 事件可能會觸發多次,每一次觸發 data 事件時,獲取到數據只是完整數據的一部分,需要手動對接收到的數據進行拼接;
當請求體數據接收完畢之后,會自動觸發 req 的 end 事件。

// 導入系統模塊querystring 用於將HTTP參數轉換為對象格式
const querystring = require('querystring');
app.on('request', (req, res) => {
	//拼接post請求參數
	let postData = '';
	
	// post參數是通過事件的方式接受的
	// 監聽參數傳輸事件, 當請求參數傳遞的時候出發data事件, params: post請求傳輸的數據
	req.on('data', (params) => {
		console.log(params)
		postData += params
	});
	// 監聽參數傳輸完畢事件, 當參數傳遞完成的時候出發end事件
	req.on('end', () => {
		// 通過querystring模塊的parse方法解析 字符串參數postData 成對象格式並返回
		console.log(postData )
		console.log(querystring.parse(postData))
	});
});

在這里插入圖片描述


四、NodeJS服務端實現路由

1. 原生實現路由

路由是指客戶端請求地址與服務器端程序代碼的對應關系。簡單的說,就是請求什么響應什么,動態響應內容:
在這里插入圖片描述
路由實現代碼

// 當客戶端發來請求的時候
app.on('request', (req, res) => {
	// 獲取客戶端的請求路徑
	let { pathname } = url.parse(req.url);
	res.setHeader('Content-Type', 'text/html; charset=utf-8')
	
	if (pathname == '/' || pathname == '/index') {
		res.end('歡迎來到首頁');
	} else if (pathname == '/list') {
		res.end('歡迎來到列表頁頁');
	} else {
		res.end('抱歉, 您訪問的頁面出游了');
	}
});

簡單案例:

const http = require('http');
const url = require('url');
const app = http.createServer();
const querystring = require("querystring");

app.on('request', (req, res) => {
    let method = req.method.toLowerCase();
    let path = url.parse(req.url);
    let postparms = '';

    res.writeHead(200, {
        'Content-Type': 'text/html;charset=utf8'
    })

    if (method == "get") {
        switch (path.pathname) {
            case '/':
            case '/index':
                res.end('<h2>歡迎來到首頁<h2>');
                break;
            case '/list':
                res.end('<h2>歡迎來到列表頁<h2>');
                break;
            case '/login':
                res.end(`<h2>歡迎來到登錄界面</h2>
                <form method="POST" action="http://localhost:1234/success">
                    <input type="text" name="username">
                    <input type="password" name="password">
                    <input type="submit">
                </form>
                `);
                break;

            default:
                res.end('<h2 style="color: red">您訪問的頁面不存在!<h2>');
        }
    } else if (method == "post") {

        req.on('data', (parms) => {
            postparms += parms;
        })
        req.on('end', () => {
            postparms = querystring.parse(postparms);
            let username = postparms.username;
            let password = postparms.password;
            switch (path.pathname) {
                case '/success':
                    res.end("登錄成功!<br>您的用戶名為:" + username + "<br>您的密碼為" + password);
            }
        })

    }
})

app.listen(1234);
console.log('服務器已啟動,監聽1234端口,請訪問 localhost:1234');

2. 第三方模塊 router

router - npm (npmjs.com)

功能:實現路由

使用步驟:

  1. 獲取路由對象
  2. 調用路由對象提供的方法創建路由
  3. 啟用路由,使路由生效
//引入router第三方模塊並返回一個函數
const getRouter = require('router')
//通過調用getRouter()獲取路由對象router, 實際也是函數
const router = getRouter();
/*路由對象.get(參數1, 參數2)
功能:用來接收get請求
參數1:Url請求地址
參數2:當前請求處理函數, 
	req: 請求對象
	res: 響應對象
*/
router.get('/add', (req, res) => {
res.end('Hello World!')
})

/*路由對象.post()
功能:用來接收post請求
參數:與get()一樣
*/
router.post('/',(req, res) => {
    res.end();
})

/*
server: 由http模塊創建的服務器對象
通過給服務器對象添加請求事件捕獲請求並開啟路由功能
*/
server.on('request', (req, res) => {
    /*
    通過調用router()啟用路由功能,    
    router函數根據請求類型和請求地址自動匹配get()或post()
    參數說明:
    req:請求對象
    res:響應對象
    callback:當請求結束后會自動調用這個回調函數,它是必填參數
    */
	router(req, res, () => {})
    
})



五、NodeJS服務端響應靜態資源

服務器端不需要處理,可以直接響應給客戶端的資源就是靜態資源,例如CSS、JavaScript、image文件。

① 第三方模塊 mime

mime - npm

轉載文章

app.on('request', (req, res) => {
	// 獲取用戶的請求路徑
	let pathname = url.parse(req.url).pathname;

	pathname = pathname == '/' ? '/default.html' : pathname;

	// 將用戶的請求路徑轉換為實際的服務器硬盤路徑, join方法可自動生成路徑鏈接符
	let realPath = path.join(__dirname, 'public' + pathname);

	//識別當前請求文件的文件類型
	let type = mime.getType(realPath)

	// 讀取文件
	fs.readFile(realPath, (error, result) => {
		// 如果文件讀取失敗
		if (error != null) {
			res.writeHead(404, {
				'content-type': 'text/html;charset=utf8'
			})
			res.end('文件讀取失敗');
			return;
		}
		res.writeHead(200, {
			//根據類型,指定當前請求響應報文中的content-type,便於瀏覽器正確讀取文件格式
			'content-type': type
		})
		res.end(result);
	});
});

② 第三方模塊 serve-static

serve-static - npm (npmjs.com)

功能:實現靜態資源訪問服務
步驟:

  1. 引入serve-static模塊獲取創建靜態資源服務功能的方法
  2. 調用方法創建靜態資源服務並指定靜態資源服務目錄
  3. 啟用靜態資源服務功能
//導入第三方模塊'serve-static' , 並返回了一個方法
const serveStatic = require('serve-static')
/*調用返回的方法: serveStatic(參數1)
功能:實現靜態資源訪問服務功能
參數1:靜態資源文件目錄(絕對路徑)
返回值:一個方法
*/
const serve = serveStatic('public')
//server: 由http模塊創建的服務器對象
server.on('request', () => {
	/*
	啟用靜態資源服務
    方法實現過程:根據請求對象來判斷當前請求是否訪問靜態資源,如果是靜態資源,它會把靜態資源直接響應給客戶端
    callback: 請求結束后會自動調用回調函數,必填參數
    */
    serve(req, res, callback);
})
server.listen(3000)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM