Node.js實現服務器配置

Node.js 實現靜態網站功能

  • 使用http模塊初步實現服務器功能
const http = require('http');

let server = http.createServer();
server.on('request', (req, res) => {
  res.end("hello world");  //訪問瀏覽器地址127.0.0.1:3000在網頁上顯示hello world
});
server.listen(3000); //設置監聽的端口
  • 實現靜態服務器功能
    • 實現請求路徑的分發
    • 實現圖片等其他資源的訪問需要根據文件類型設置響應類型
const http = require('http');
const fs = require('fs');
const path = require('path');
const mime = require('./lib/mime.json');  //用於通過文件後綴設置響應頭

//用於讀取指定路徑的文件內容並返回到瀏覽器
let readFile = (dpath, res) => {
  fs.readFile(path.join(__dirname, 'www', dpath), (err, fileContent) => {
    if (err) {
      //第一個參數爲響應狀態碼
      res.writeHead(404, {
        'Content-Type': 'text/plain;charset=utf8'//設置響應類型和編碼,解決亂碼
      })
      res.end("404頁面找不到了");//終止響應,不可以多次寫入
    } else {
      let dtype = "text/html";  //設置默認類型
      let ext = path.extname(dpath);
      if (mime[ext]) {
        dtype = mime[ext];  //通過文件後綴獲取對應類型
      }

      if (dtype.startsWith('text')) {
        dtype += ';charset=utf8';  //響應內容爲文本的時候設置編碼
      }
      res.writeHead(200, {
        'Content-Type': dtype
      })
      res.end(fileContent);
    }
  })
}


http.createServer((req, res) => {
  //res.end(req.url);  //獲取到端口之後的路徑
  if (req.url.startsWith('/index')) {
    //res.write("訪問了");  //向客戶端響應內容,可以寫入多次
    readFile(req.url, res);
  } else if (req.url.startsWith('/list')) {
    readFile(req.url, res);
  } else if (req.url.startsWith('/detail')) {
    readFile(req.url, res);
  }
  
  //以上的if判斷可以省略,直接調用 readFile(req.url, res); 即可
}).listen(3000, '192.168.1.104', () => {  //該ip爲本電腦連接wifi後的IP地址,可省略則默認爲127.0.0.1
  console.log("服務running");
})

參數傳遞與獲取

  • get參數獲取
    • url.parse(urlString) 將url字符串轉爲對象,第二個參數可傳入true表示將對參數url進行querystring.parse解析
    • url.format(urlObject) 將url對象轉爲字符
const url = require('url');
let myURL =
  url.parse('http://user:[email protected]:8080/p/a/t/h?query=string#hash');
console.log(myURL);
url.format(myURL);
/*
Url {
  protocol: 'http:', //協議
  slashes: true,  //當Url協議中的冒號後面包含雙斜槓/則爲true
  auth: 'user:pass',  //用戶名密碼認證信息
  host: 'sub.example.com:8080', //包含端口號的域名
  port: '8080',   //端口
  hostname: 'sub.example.com',    //不包含端口號的域名
  hash: '#hash',  //錨點
  search: '?query=string',   //問號以及所有參數
  query: 'query=string',   //去掉問號後的所有參數
  pathname: '/p/a/t/h',     //域名後之後不包含參數的路徑
  path: '/p/a/t/h?query=string',    //包含參數的路徑
  href: 'http://user:[email protected]:8080/p/a/t/h?query=string#hash'  //url完整字符串
}
*/
  • get請求處
const http = require('http');
const ss = require('./staticServer.js');
const path = require('path');
const url = require('url');

http.createServer((req, res) => {
  let urlObj = url.parse(req.url, true);
  res.end(urlObj.query.username + '-' + urlObj.query.pass);
}).listen(3000, () => {
  console.log("服務running");
})

//測試:http://127.0.0.1:3000/index.html?username=hym&pass=12
  • post參數獲取
    • querystring.parse(urlstr) 將字符串轉爲對象,當多個參數一樣時,將參數的值放入數組中
    • querystring.stringify(obj) 將對象中的參數拼接成字符串(自動拆分數組)
const querystring = require('querystring');
let param = 'foo=bar&abc=xyz&abc=123';
let obj = querystring.parse(param);
console.log(obj);
/* {
  foo: 'bar',
  abc: ['xyz', '123']
} */

let str = querystring.stringify(obj);
console.log(str);
/* foo=bar&abc=xyz&abc=123 */
  • post請求處
const http = require('http');
const querystring = require('querystring');
http.createServer((req, res) => {
  if (req.url.startsWith('/login')) {
    let allData = '';
    req.on('data', (chunk) => {
      allData += chunk;    //將接受的數據拼接完整
    });

    req.on('end', () => {
      console.log(allData);
      let obj = querystring.parse(allData);
      res.end(obj.username + "-" + obj.pass);
    })
  }
}).listen(3000, () => {
  console.log("服務running···");
})

//測試:使用chrome插件postman模擬發送post請求,參數格式選擇www-form-urlencoded

動態網站

創建服務器實現動態網站的效果

  • 路由 即請求路徑+請求方式
  • .tpl 模板文件
//visual studio code中將.tpl文件識別爲html文件並高亮 
// 將設置放入file --> preferences --> settings
//-->Text Editor --> Files --> Edit in settings.json文件中以覆蓋默認設置
{
    "files.associations": {
        "*.tpl":"html"
    }
}
<!--創建模板文件query用於輸入關鍵字、result.tpl用於存放查詢的結果-->
<body>
  <table>
    <tr>
      <th>英文</th>
      <th>中文</th>
      <th>應用場景</th>
    </tr>
    <tr>
      <td>$$english$$</td>
      <td>$$chinese$$</td>
      <td>$$application$$</td>
    </tr>
  </table>
</body>
  • node服務(需要準備虛擬數據search.json文件)
const http = require('http');
const path = require('path');
const fs = require('fs');
const querystring = require('querystring');
const virtualData = require('./virtualData/search.json');

http.createServer((req, res) => {
  //查詢入口 /query
  if (req.url.startsWith('/query') && req.method == 'GET') {
    fs.readFile(path.join(__dirname, 'www/view', 'query.tpl'), 'utf8', (err, content) => {
      if (err) {
        res.writeHead(500, {
          'Content-Type': 'text/plain;charset=utf8'
        });
        res.end("500服務器錯誤!")
      }

      res.end(content);
    })
  } else if (req.url.startsWith('/result')) {
    let allData = '';
    req.on('data', (chunk) => {
      allData += chunk;
    });

    req.on('end', () => {
      let obj = querystring.parse(allData);
      let result = virtualData[obj.key];
      fs.readFile(path.join(__dirname, 'www/view', 'result.tpl'), 'utf8', (err, content) => {
        if (err) {
          res.writeHead(500, {
            'Content-Type': 'text/plain;charset=utf8'
          });
          res.end("500服務器錯誤!")
        }

        //進行數據渲染
        content = content.replace('$$english$$', result.english);
        content = content.replace('$$chinese$$', result.chinese);
        content = content.replace('$$application$$', result.application);
        //或者使用模板引擎art-template
        //let html = template(path.join(__dirname, 'www/view', 'result.art'), result)
        res.end(content);
      })
    })
  }
}).listen(3000, () => {
  console.log("服務running···")
})
  • 案例:實現登錄驗證功能
const http = require('http');
const querystring = require('querystring');
const ss = require('./staticServer.js');

http.createServer((req, res) => {
  //啓動靜態資源服務
  if (req.url.startsWith('/www')) {
    ss.staticServer(req, res, __dirname);
  }

  //啓動動態服務
  if (req.url.startsWith('/login')) {
    //get請求處理
    if (req.method == 'GET') {

    }
    //post請求處理
    if (req.method == 'POST') {
      let allData = '';
      req.on('data', (chunk) => {
        allData += chunk;
      });

      req.on('end', () => {
        let obj = querystring.parse(allData);
        res.writeHead(500, {
          'Content-Type': 'text/plain;charset=utf8'  //防止中文亂碼
        });
        if (obj.username == 'admin' && obj.pass == 'root') {
          res.end('登錄成功');
        } else {
          res.end('登錄失敗');
        }
      });
    }
  }
}).listen(3000, () => {
  console.log("服務running···")
}) 

模板引擎 art-template

  • 理解模板引擎本質
  • 引擎基本使用
const path = require('path');
var template = require('art-template');

//使用方式一:創建好.art文件
var html = template(path.join(__dirname, '../mytpl.art'), {
  user: {
    name: 'aui'
  }
});

console.log(html);

//使用方式二:字符串形式
/* let tpl = '<ul>{{each list value index}}<li>{{index}}{{value}}</li>{{/each}}</ul>';
let render = template.compile(tpl);
let ret = render({
  list: ['english', 'math', 'chinese']
});
console.log(ret); */

//使用方式三:簡單化
/* let tpl = '<ul>{{each list}}<li>{{$index}}{{$value}}</li>{{/each}}</ul>';
let ret = template.render(tpl, {
  list: ['english', 'math', 'chinese']
});
console.log(ret); */
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章