• 使用Node.js搭建一个简单的web服务器(二):搭建一个简单的服务器


    创建一个服务器

    基本配置:

    const http = require('http');
    
    const server = http.createServer((req, res) => {//req:请求对象,res:响应对象
      console.log(`request was made: ${req.url}`);//req.url描述原始的请求路径
      //向请求发送响应头,在res.end()前使用
      res.writeHead(200, { 'Content-Type': 'text/plain' });
      //向服务器发出信号,表明已发送所有响应头和主体,该服务器视为此消息已完成必须在每个响应上调用此方法
      res.end('Hey ting');
    });
    
    server.listen(3000, '127.0.0.1');//监听127.0.0.1:3000
    console.log('yo dawgs, now listening to port 3000');
    

    buffers&streams

    buffers

    • 从一处转移到另一处的大量数据的临时储存点
    • 当缓冲区充满了数据,然后开始传输
    • 一次传输一小块数据

    streams in node.js

    • 可以在node.js中创建流传输数据
    • 提高性能

    通过streams读或写数据

    创建指定文件的可读流和可写流,通过streams更高效的实现文件的读写操作。

    const fs = require('fs');
    
    const myReadStream = fs.createReadStream(`${__dirname}/readMe.txt`, 'utf8');
    const myWriteStream = fs.createWriteStream(`${__dirname}/writeMe.txt`)
    
    myReadStream.on('data', (chunk) => {
    //将从readMe中读取的每块数据块写入writeMe文件
      console.log('new chunk received:');
      myWriteStream.write(chunk);
    })
    

    pipes

    将可写流绑定到可读流,将可读流自动切换到流动模式,并将可读流所有数据推送到可写流。数据流会被自动管理。

    const http = require('http');
    const fs = require('fs');
    
    const server = http.createServer((req, res) => {
      // res is a writeable stream
      console.log(`request was made: ${req.url}`);
      res.writeHead(200, { 'Content-Type': 'text/plain' });
      const myReadStream = fs.createReadStream(`${__dirname}/readMe.txt`, 'utf8');
      myReadStream.pipe(res);//将从readMe读取的数据都作为返回的数据返回
      
    });
    
    server.listen(3000, '127.0.0.1');
    console.log('yo dawgs, now listening to port 3000');
    

    在客户端显示HTML页面

    将content-type改为text/html

    const server = http.createServer((req, res) => {
      // res is a writeable stream
      console.log(`request was made: ${req.url}`);
      res.writeHead(200, { 'Content-Type': 'text/html' });
      const myReadStream = fs.createReadStream(`${__dirname}/index.html`, 'utf8');
      // const myWriteStream = fs.createWriteStream(`${__dirname}/writeMe.txt`)
      myReadStream.pipe(res);
      
    });
    

    在客户端显示JSON格式数据

    const server = http.createServer((req, res) => {
      // res is a writeable stream
      console.log(`request was made: ${req.url}`);
      res.writeHead(200, { 'Content-Type': 'application/json' });
      //修改content-type
      const myObj = {
        name: 'Ryu',
        job: 'ninja',
        age: 20
      }
      res.end(JSON.stringify(myObj))
      //将JSON结构数据以字符串的形式输出,否则输出为[object,object]
    });
    

    基本路由配置

    通过判断请求的路由进行页面配置,使路由与页面相对应。

    const http = require('http');
    const fs = require('fs');
    
    const server = http.createServer((req, res) => {
      // res is a writeable stream
      console.log(`request was made: ${req.url}`);
      if (req.url === '/home' || req.url === '/') {//首页
        res.writeHead(200, { 'Content-Type': 'text/html' });
        fs.createReadStream(`${__dirname}/index.html`, 'utf8').pipe(res);
      } else if (req.url === '/contact') {//联系页面
        res.writeHead(200, { 'Content-Type': 'text/html' });
        fs.createReadStream(`${__dirname}/contact.html`, 'utf8').pipe(res);
      } else if (req.url === '/api/ting') {//JSON
        let ting = [{name: 'ting', age: 20}, {name: 'xu', age: 21}]
        res.writeHead(200, {'Content-Type': 'application/json'})
        res.end(JSON.stringify(ting))
      } else {//404 找不到页面
        res.writeHead(404, { 'Content-Type': 'text/html' });
        fs.createReadStream(`${__dirname}/404.html`, 'utf8').pipe(res);
      }
    });
    
    server.listen(3000, '127.0.0.1');
    console.log('yo dawgs, now listening to port 3000');
    
    

    nodemon Node自动启动工具

    监听代码文件变动并自动重启
    安装:

    npm install nodemon -g
    

    启动:

    nodemon app.js
    

    Express

    Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。

    HTTP methods

    • GET -app.get('route', fn)
    • POST -app.post('route', fn)
    • DELETE -app.delete('route', fn)
    • PUT

    express基本使用

    let express = require('express');//导入
    
    let app = express();
    
    app.get('/', (req, res) => {//使用HTTP GET方法请求特定路由,并在回调方法(即middleware function)中对请求及相应做处理
      res.send('this is the homepage')
    });
    app.get('/contact', (req, res) => {
      res.send('this is the contactpage')
    });
    app.get('/contact', (req, res) => {
      res.sendFile(`${__dirname}/contact.html`)//使用sendFile方法返回对应HTML页面
    });
    
    app.get('/profile/:id', (req, res) => {//"/:id"是动态的,可以是任意值
      res.send('You requested to see a profile with the id of ' + req.params.id)
    })
    
    app.listen(3000);
    

    中间件方法(middleware function)

    即在请求和相应之间执行的方法,可以通过中间件对HTTPRequest对象和HTTPResponse对象做一些操作,或在view执行之前做一些操作。

    EJS (JavaScript模板引擎)

    基本使用(数据输出)

    利用JavaScript代码在生成的HTML页面中输出数据
    使用<%= ...> 在页面中输出数据

    let express = require('express');
    
    let app = express();
    app.set('view engine', 'ejs')
    
    app.get('/profile/:id', (req, res) => {
      let data = {
        age: 22,
        job: 'ninja'
      }
      res.render('profile', {person: req.params.id, data: data})
      //渲染views中的profile.ejs并传入第二个参数中的数据
    })
    
    app.listen(3000);
    
    //ejs部分,将从render方法中传入的数据对应输出
    <body>
      <h1>weclome to the profile of <%= person %> </h1>
      <p><strong>Age:</strong><%= data.age %></p>
      <p><strong>Job:</strong><%= data.job %></p>
    </body>
    


    实现数据遍历输出

    <body>
      <h1>weclome to the profile of <%= person %> </h1>
      <p><strong>Age:</strong><%= data.age %></p>
      <p><strong>Job:</strong><%= data.job %></p>
      <h2>Hobbies</h2>
      <ul>
        <% data.hobbies.forEach((item) => { %>
          <li><%= item %></li>
        <% }); %>
      </ul>
    </body>
    

    复用模板

    如设置复用nav模板,就可以省去在每一个页面重复写nav代码的步骤。通过include指令将相对于模板路径中的模板片段包含进来

    //nav
    <nav>
      <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/contact">Contact</a></li>
      </ul>
    </nav>
    

    在页面相应位置添加一下代码,即包含partial文件下nav.ejs文件内容

    <%- include('partial/nav') %>  
    

    设置静态样式

    将静态样式放在assets文件夹下并通过link标签获取,因为设置的样式文件没有像之前的HTML文件或EJS文件一样通过中间件方法放到相应的请求响应中,所以不会在页面显示,为了不在每个请求get请求方法中重复同样的代码,使用express的use方法(对给定的路径做相应的处理)及 express.static()方法设置静态文件
    use([path],callback)方法用来给path注册中间件,在实际请求发生之前对HTTPrequest和HTTPresponse做一些操作
    express.static()方法是一个express内置的中间件方法,用来提供静态资源文件

    //html文件
       <link rel="stylesheet" href="/assets/styles.css" type="text/css" />
    
    app.use('/assets', express.static('public'))
    //当请求路径以/assets为根路径时,将请求交给中间件处理
    //假设public文件夹下有styles.css文件,则可通过/assets/styles.css访问
    

    query strings

    • mysite.com/blog/news?page=2
    • page=2
    • mysite.com/contact?person=ryu&dept=marking
    • 解析请求,并提取数据
    app.get('/contact', (req, res) => {
      res.render('contact', {qs: req.query})
    });
    
    <body>
      <%- include('partial/nav') %>
      <h1>Contact US!</h1>
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur, alias.</p>
      <form id="contact-form">
        <label for="who">Who do you want to contact?</label>
        <input type="text" name="who" value="<%= qs.person %>" />
        <label for="department">Which department?</label>
        <input type="text" name="department" value="<%= qs.dept %>" />
        <label for="email">Your email</label>
        <input type="email" name="email" />
        <input type="submit" value="submit" />
      </form>
    </body>
    


    POST 请求

    • POST 是一个网络请求方法
    • POST请求服务器接收/存储请求正文中包含的数据
    • 常在表单提交中使用


    var urlencodedParser = bodyParser.urlencoded({ extended: false });
    
    app.post('/contact', urlencodedParser, (req, res) => {
      console.log(req.body)
      res.render('contact-success', {data: req.body})
    });
    
    <body>
      <%- include('partial/nav') %>
      <h1>Contact US!</h1>
      <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Tenetur, alias.</p>
      <p>Thanks for getting in touch!</p>
      <p>You contacted <%= data.who %> in the <%= data.department %> department.</p>
      <p>We will reply you at <%= data.email %></p>
    </body>
    
  • 相关阅读:
    计算机网络基础,子网掩码,网络号,子网号,主机号主机数量计算方式
    Nginx配置大全与搭建手册
    Windows10仿mac-os主题
    kali-linux知识整理与渗透测试指南
    简单的钓鱼网站制作-Setoolkit
    渗透测试常用工具-Metasploit_常用模块
    提权方式及原理简介(面试)
    修改dedecms精简版
    内网存活主机探测的一些方法
    免杀测试
  • 原文地址:https://www.cnblogs.com/xuewting/p/13216171.html
Copyright © 2020-2023  润新知