1. url.parse(url)解析
該方法將一個URL字符串轉換成對象並返回。
url.parse(urlStr, [parseQueryString], [slashesDenoteHost])
接收參數:
urlStr url字符串
parseQueryString 為true時將使用查詢模塊分析查詢字符串,默認為false
我們通過解析HTTP請求,從中提取出請求的URL以及GET/POST參數。url是nodejs內置的一個模板,我們需要require("url")獲取,下面的url:http://localhost:8888/start?foo=bar&hello=world,通過url.parse解析出的一個對象的各個字段名對應url的各部分。
var url = require('url'); var queryUrl = "http://localhost:8888/start?foo=bar&hello=world" ; console.log(typeof url.parse(queryUrl)) ; console.log(url.parse(queryUrl)) ; //輸出結果如下: /* object // typeof { protocol: 'http:', slashes: true, auth: null, host: 'localhost:8888', port: '8888', hostname: 'localhost', hash: null, search: '?foo=bar&hello=world', query: 'foo=bar&hello=world', pathname: '/start', path: '/start?foo=bar&hello=world', href: 'http://localhost:8888/start?foo=bar&hello=world' } 加以說明如下: protocol: 請求協議 host: URL主機名已全部轉換成小寫, 包括端口信息 auth:URL中身份驗證信息部分 hostname:主機的主機名部分, 已轉換成小寫 port: 主機的端口號部分 pathname: URL的路徑部分,位於主機名之后請求查詢之前 search: URL 的“查詢字符串”部分,包括開頭的問號。 path: pathname 和 search 連在一起。 query: 查詢字符串中的參數部分(問號后面部分字符串),或者使用 querystring.parse() 解析后返回的對象。 hash: URL 的 “#” 后面部分(包括 # 符號) */
用下面的圖更形象的描述說明給大家:
url.parse(string).query | url.parse(string).pathname | | | | | ------ ------------------- http://localhost:8888/start?foo=bar&hello=world --- ----- | | | | querystring(string)["foo"] | | querystring(string)["hello"]
2. 路由選擇實現代碼
處理不同的HTTP請求在我們的代碼中是另外一個不同的部分,叫做“路由選擇”。
那么,我們接下來就創造一個叫做 路由 的模塊吧。
新建屬於服務器端的路由文件router.js
1 //-----------------router.js-------------------------------- 2 module.exports={ 3 login:function(req,res){ 4 res.write("我是login方法"); 5 }, 6 register:function(req,res){ 7 res.write("我是注冊方法"); 8 } 9 }
服務端調用路由,方式和上一節課《nodejs進階2--函數模塊調用》中最后提到的字符串調用函數一樣。
1 //---------4_router.js----------- 2 var http = require('http'); 3 var url = require('url'); 4 var router = require('./router'); 5 http.createServer(function (request, response) { 6 response.writeHead(200, {'Content-Type': 'text/html; charset=utf-8'}); 7 if(request.url!=="/favicon.ico"){ 8 var pathname = url.parse(request.url).pathname;//得到請求的路徑 9 console.log(pathname); 10 pathname = pathname.replace(/\//, '');//替換掉前面的/ 11 console.log(pathname); 12 router[pathname](request,response); 13 response.end(''); 14 } 15 }).listen(8000); 16 console.log('Server running at http://127.0.0.1:8000/');
上面我們用到了node自帶模塊url。url.path(urlStr):將一個URL字符串轉換成對象並返回。
3. 向頁面輸出html文件
對於一般的get請求,例如localhost/login 我們需要給瀏覽器輸出個頁面login.html,那我們怎么做呢?
首先我們新增兩個頁面
1.login.html
1 <html> 2 <head> 3 </head> 4 <body> 5 登錄: 6 <p>這是一個段落</p> 7 <h1>樣式1</h1> 8 </body> 9 <html>
2.register.html
1 <html> 2 <head> 3 </head> 4 <body> 5 注冊: 6 <p>這是一個段落</p> 7 <h1>樣式1</h1> 8 </body> 9 <html>
讀取文件的方法,我們放到文件models/file.js里
1 //-------------models/file.js------------------------- 2 var fs= require('fs'); 3 module.exports={ 4 readfile:function(path,callback){ //異步讀文件,需要傳入回調函數 5 fs.readFile(path, function (err, data) { 6 if (err) { 7 console.log(err); 8 }else{ 9 callback(data); 10 } 11 }); 12 console.log("異步方法執行完畢"); 13 }, 14 readfileSync:function(path){ //同步讀取 15 var data = fs.readFileSync(path,'utf-8'); 16 console.log("同步方法執行完畢"); 17 return data; 18 } 19 }
router.js需要調用文件讀取方法,把兩個頁面html文件讀取出內容並輸出到response。需要注意的是:res.end()這句話的位置,如果用異步讀文件的方法就不能放到server創建那塊了
1 //-----------------router.js-------------------------------- 2 var file = require('./models/file'); 3 module.exports={ 4 login:function(req,res){ 5 var callback=function(data){ 6 res.write(data); 7 res.end(); 8 } 9 file.readfile('./views/login.html',callback);//使用異步讀取 10 }, 11 register:function(req,res){ 12 var data=file.readfileSync('./views/register.html');//使用同步讀取 13 res.write(data); 14 res.end(); 15 } 16 }
我們重新運行:node 4_router.js。分別在瀏覽器輸入http://localhost:8000/login 和http://localhost:8000/register ,輸出了login.html和register.html頁面的內容。