• Create First Application


    Node.js创建第一个应用

    Node.js开发的目的就是为了用JavaScript编写Web服务器程序, 在使用Node.js时,不仅仅是在实现一个应用,同时还实现了整个HTTP服务器。在创建Node.js第一个"Hello, World!"应用前,需先了解下Node.js应用是由哪几部分组成的:

    1. 引入require模块: 使用require指令载入Node.js模块
    2. 创建服务器: 服务器可以监听客户端的请求,类似于Apache、Nginx等HTTP服务器
    3. 接收请求与响应请求: 客户端可以使用浏览器或终端发送HTTP请求,服务器接收请求后返回响应数据

    HTTP协议

    要理解Web服务器程序的工作原理,首先,要对HTTP协议有基本的了解HTTP协议简介

    HTTP服务器

    开发HTTP服务器程序, 从头处理TCP连接, 解析HTTP是不现实的. 这些工作实际上已经由Node.js自带的http模块帮我们完成了. 应用程序并不直接和HTTP协议打交道, 而是操作http模块提供的requestresponse对象.

    request对象封装了HTTP请求,调用request对象的属性和方法就可以得到所有HTTP请求的信息;

    response对象封装了HTTP响应,操作response对象的方法,就可以把HTTP响应返回给浏览器;

    用Node.js实现一个HTTP服务器程序。首先实现一个最简单的Web程序hello.js,它对于所有请求,都返回Hello world!:

    步骤一、引入require模块

    const http = require('http');
    

    步骤二、创建服务器

    使用http.createServer()方法创建服务器,并使用listen方法绑定8080端口. 函数通过request, response参数来接收和响应数据

    const http = require('http');
    
    http.createServer(function (request, response) {
    
        // 发送 HTTP 头部 
        // HTTP 状态值: 200 : OK
        // 内容类型: text/plain
        response.writeHead(200, {'Content-Type': 'text/plain'});
    
        // 发送响应数据 "Hello World"
        response.end('Hello World!
    ');
    }).listen(8080);
    
    // 终端打印如下信息
    console.log('Server running at http://127.0.0.1:8080/');
    
    'use strict';
    
    // 导入http模块:
    const http = require('http');
    
    // 创建http server,并传入回调函数:
    const server = http.createServer(function (request, response) {
        // 回调函数接收request和response对象,
        // 获得HTTP请求的method和url:
        console.log(request.method + ': ' + request.url);
        // 将HTTP响应200写入response, 同时设置Content-Type: text/html:
        response.writeHead(200, {'Content-Type': 'text/html'});
        // 将HTTP响应的HTML内容写入response:
        response.end('<h1>Hello world!</h1>');
    });
    
    // 让服务器监听8080端口:
    server.listen(8080);
    
    console.log('Server is running at http://127.0.0.1:8080/');
    
    'use strict';
    
    // 导入http模块:
    const http = require('http');
    
    // 创建http server,并传入回调函数:
    const server = http.createServer((request, response) => {
        // 回调函数接收request和response对象,
        // 获得HTTP请求的method和url:
        console.log(request.method + ': ' + request.url);
        // 将HTTP响应200写入response, 同时设置Content-Type: text/html:
        response.writeHead(200, {'Content-Type': 'text/html'});
        // 将HTTP响应的HTML内容写入response:
        response.end('<h1>Hello world!</h1>');
    });
    
    // 让服务器监听8080端口:
    server.listen(8080);
    
    console.log('Server is running at http://127.0.0.1:8080/');
    

    在命令行下运行该文件,可以看到以下输出:

    $ node hello.js 
    Server is running at http://127.0.0.1:8080/
    

    不要关闭命令提示符,直接打开浏览器输入http://localhost:8080,即可看到服务器响应的内容:

    同时,在命令提示符窗口,可以看到程序打印的请求消息:

    GET: /
    GET: /favicon.ico
    

    文件服务器

    继续扩展上面的Web程序, 可以设定一个目录,然后让Web程序变成一个文件服务器。要实现这一点,只需解析request.url中的路径,然后在本地找到对应的文件,把文件内容发送出去就可以了。

    解析URL需要用到Node.js提供的url模块,它使用起来非常简单,通过parse()将一个字符串解析为一个Url对象:

    'use strict';
    
    const url = require('url');
    
    console.log(url.parse('http://user:pass@host.com:8080/path/to/file?query=string#hash'));
    

    结果如下:

    Url {
      protocol: 'http:',
      slashes: true,
      auth: 'user:pass',
      host: 'host.com:8080',
      port: '8080',
      hostname: 'host.com',
      hash: '#hash',
      search: '?query=string',
      query: 'query=string',
      pathname: '/path/to/file',
      path: '/path/to/file?query=string',
      href: 'http://user:pass@host.com:8080/path/to/file?query=string#hash'
    }
    

    处理本地文件目录需要使用Node.js提供的path模块,它可以方便地构造目录:

    'use strict';
    
    const path = require('path');
    
    // 解析当前目录
    const workDir = path.resolve('.');
    
    // 组合完整的文件路径:当前目录 + 'static' + 'index.html'
    const filePath = path.join(workDir, 'static', 'index.html');
    
    console.log(workDir);
    console.log(filePath);
    // D:NodejsAppmiddlewareworkdir
    // D:NodejsAppmiddlewareworkdirstaticindex.html
    

    使用path模块可以正确处理操作系统相关的文件路径。在Windows系统下,返回的路径类似于C:UsersUnitystaticindex.html,这样,就不必关心怎么拼接路径了。最后,实现文件服务器file_server.js

    'use strict';
    
    const fs = require('fs');
    const url = require('url');
    const path = require('path');
    const http = require('http');
    
    // 从命令行参数获取root目录,默认是当前目录
    const root = path.resolve(process.argv[2] || '.');
    
    console.log(`Stctic root dir: ${root}`);
    
    // 创建服务器
    http.createServer((request, response) => {
        // 获得URL的path,类似/css/bootstrap.css
        const pathname = url.parse(request.url).pathname;
    
        // 获得对应的本地文件路径,类似/src/css/bootstrap.css
        const filepath = path.join(root, pathname);
    
        // 获取文件状态
        fs.stat(filepath, (err, stats) => {
            if (!err && stats.isFile()) {
                // 没有出错并且文件存在
                console.log('200' + request.url);
                // 发送200响应
                response.writeHead(200);
                // 将文件流导向response
                fs.createReadStream(filepath).pipe(response);
            } else {
                // 出错或文件不存在
                console.log('404' + request.url);
                // 发送404
                response.writeHead(404);
                response.end('404 Not Found');
            }
        });
    }).listen(8080);
    
    console.log('Server is running at http://127.0.0.1:8080/');
    

    没有必要手动读取文件内容, 由于response对象本身是一个Writable Stream,直接用pipe()方法就实现了自动读取文件内容并输出到HTTP响应

    在命令行运行node file_server.js 然后在浏览器中输入http://localhost:8080/index.html

    只要当前目录下存在文件index.html,服务器就可以把文件内容发送给浏览器。观察控制台输出

    200 /index.html
    200 /css/uikit.min.css
    200 /js/jquery.min.js
    200 /fonts/fontawesome-webfont.woff2
    

    第一个请求是浏览器请求index.html页面,后续请求是浏览器解析HTML后发送的其它资源请求

    练习

    在浏览器输入http://localhost:8080/时,会返回404,原因是程序识别出HTTP请求的不是文件,而是目录。请修改file_server.js,如果遇到请求的路径是目录,则自动在目录下依次搜索index.htmldefault.html,如果找到了,就返回HTML文件的内容。

    参考源码

    http服务器代码(含静态网站)

  • 相关阅读:
    SourceInsight宏插件3(非常好用,强力推荐)
    SourceInsight宏插件2(非常好用,强力推荐)
    Beyond Compare 3添加右键菜单
    OpenCV图像读取和写入
    TY科技的工程配置(VS2017 & Opencv4.0.0)
    Visual Studio2017 & pcl1.8.1 库的配置
    LeetCode No.198
    LeetCode No.191
    LeetCode No.190
    LeetCode No.179**
  • 原文地址:https://www.cnblogs.com/PrimerPlus/p/12932362.html
Copyright © 2020-2023  润新知