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); */
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章