Node中的Connect

2023-05-16

来自对《了不起的Node.js》一书的学习

Connect

  1. Node.js为常规的网络应用提供了基本的API。然而,实际情况下,绝大部分网络应用都需要完成一系列类似的操作,这些类似的操作你一定不想每次都重复地基于原始的API去实现。
  2. Connect是一个基于HTTP服务器的工具集,它提供了一种新的组织代码的方式来与请求、响应对象进行交互,称为中间件(middleware)。
  3. 中间件具有代码复用的好处。

案例

  需求:实现一个后台服务,能响应浏览器请求站点目录下的images下的.jpg图片,并返回图片。

使用HTTP构建一个简单的网站

  1. 创建server.js,实现该服务器的基本功能(解析请求的URL地址,根据不同的URL请求,对应不同的操作,如:请求.jpg图片),代码如下所示:
/**
 * 模块依赖
 */
var http = require('http'),
    fs = require('fs');

/**
 * 创建服务器
 */
var server = http.createServer(function(req, res) {
    // 检查URL是否和服务器目录下的文件匹配,如果匹配,则读取该文件并展示出来
    // 请求.jpg图片
    if('GET' == req.method 
        && '/images' == req.url.substr(0, 7) 
        && '.jpg' == req.url.substr(-4)) {
        // 返回对应图片
        // ...

    } else if('GET' == req.method && '/' == req.url) {
        // 发送html文件,默认请求index.html
        // ...

    } else {
        // 处理其他请求,返回404错误码
        res.writeHead(404);
        res.end('Not found');
    }

});

server.listen(3000);

  接下来的任务,当然是完成处理对应的请求。
2. 首先是请求图片时,使用fs.stat来检查文件是否存在。这里使用Node中的全局常量__dirname来获取当前服务器所在的路径。在

        // 返回对应图片

代码下,增加对应操作:

fs.stat(__dirname + req.url, function(err, stat) {
            // 如果检查文件是否存在时发生错误,则终止进程并发送HTTP 404状态码告知无法找到请求的图片。
            // 对于stat成功但是路径所表示的并非是文件时,也要做此处理。
            if(err || !stat.isFile()) {
                res.writeHead(404);
                res.end('Not Found');
                return;
            }

            // 发送图片资源
        });

  接下来解决的问题是,发送图片资源或文件资源的问题,实际上也是服务器返回响应消息的问题。那么想想,如何返回呢?我们需要设置响应消息的Content-Type头信息,告诉浏览器,现在服务器将返回什么类型的数据。
3. 对于返回图片资源或文件资源的操作,区别只于在文件的路径和Content-Type头信息的不同而已,那么可以封装为如下方法:

    /**
     * 根据文件路径来获取文件内容,并添加'Content-Type'头信息
     * @param  {[type]} path 文件路径
     * @param  {[type]} type Content-Type头信息
     * @return {[type]}      [description]
     */
    function server(path, type) {
        res.writeHead(200, {'Content-Type': type});
        fs.createReadStream(path).pipe(res);
    }

  在对应 发送图片资源 的注释处,添加如下代码:

    // 发送图片资源
    serve(__dirname + req.url, 'application/jpg');

  在对应 发送html文件 的注释处,添加如下代码:

    // 发送html文件,默认请求index.html
    // ...
    serve(__dirname + '/index.html', 'text/html');

  server.js完成!
4. 此外,补充一下 index.html 的内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用HTTP构建一个简单的网站</title>
    <style>
        img {
            width: 300px;
        }
    </style>
</head>
<body>
    <h1>My website</h1>
    <img src="./images/1.jpg" alt="1.jpg">
    <img src="./images/2.jpg" alt="2.jpg">
    <img src="./images/3.jpg" alt="3.jpg">
    <img src="./images/4.jpg" alt="4.jpg">
</body>
</html>

  简单的显示4张图片(其实对应的就是4个请求.jpg图片资源的请求)。
5. 运行 node server.js,在浏览器中访问 http://127.0.0.1:3000,就能看到刚实现的网站了!如:
使用HTTP构建一个简单的网站
  server.js的完整代码如下:

/**
 * 模块依赖
 */
var http = require('http'),
    fs = require('fs');

/**
 * 创建服务器
 */
var server = http.createServer(function(req, res) {
    // 检查URL是否和服务器目录下的文件匹配,如果匹配,则读取该文件并展示出来
    // 请求.jpg图片
    if('GET' == req.method 
        && '/images' == req.url.substr(0, 7) 
        && '.jpg' == req.url.substr(-4)) {
        // 返回对应图片
        // ...
        fs.stat(__dirname + req.url, function(err, stat) {
            // 如果检查文件是否存在时发生错误,则终止进程并发送HTTP 404状态码告知无法找到请求的图片。
            // 对于stat成功但是路径所表示的并非是文件时,也要做此处理。
            if(err || !stat.isFile()) {
                res.writeHead(404);
                res.end('Not Found');
                return;
            }

            // 发送图片资源
            serve(__dirname + req.url, 'application/jpg');
        });

    } else if('GET' == req.method && '/' == req.url) {
        // 发送html文件,默认请求index.html
        // ...
        // console.log(__dirname);
        serve(__dirname + '/index.html', 'text/html');
    } else {
        // 处理其他请求,返回404错误码
        res.writeHead(404);
        res.end('Not found');
    }


    /**
     * 根据文件路径来获取文件内容,并添加'Content-Type'头信息
     * @param  {[type]} path 文件路径
     * @param  {[type]} type Content-Type头信息
     * @return {[type]}      [description]
     */
    function serve(path, type) {
        res.writeHead(200, {'Content-Type': type});
        fs.createReadStream(path).pipe(res);
    }
});

server.listen(3000);

通过Connect实现一个简单的网站

  接下来这个例子是要实现一个网站,该例子展示了创建网站时一些常见的任务:
  - 托管静态文件。
  - 处理错误以及损坏或者不存在的URL。
  - 处理不同类型的请求。
  基于http模块API之上的Connect,提供了一些工具方法能够让这些重复性的处理便于实现,以至于让开发者能够更加专注在应用本身。
1. 初始化项目——npm init,创建package.json文件,并在其中声明对“connect”模块的依赖:

{
  "name": "my-website",
  "version": "0.0.1",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "connect": "1.8.7"
  }
}

  使用 npm install 命令安装依赖。
2. 在server.js中使用use()方法来添加static中间件。(中间件是什么呢?我也不清楚耶,快看到下一节了。中间件,其实就是一个简单的JavaScript函数。)

/**
 * 模块依赖
 */
var connect = require('connect');

/**
 * 创建服务器
 */
var server = connect.createServer();

/**
 * 处理静态文件
 * 这里,我们配置static中间件——通过传递一些参数给connect.static方法,该方法本身会返回一个方法
 * (被返回的方法应该是中间件吧~)
 */
server.use(connect.static(__dirname + '/website'));

server.listen(3000);

  运行 node server.js(啊?这就好了?!刚写一堆,现在用了Connect模块就几行而已了?没错,是的)。试着在浏览器访问,成功见到index.html的样子了!那我们访问不存在的url呢(事实上,Connect会帮我们处理404的情况),例如,我们可以访问 /test 来验证。浏览器将显示如下结果:

Cannot GET /test

  注:记得把index.html 和 images文件夹等静态资源放置到项目目录下的website文件夹下。

中间件

  在没有使用中间件的情况下,处理请求的这些代码都放在一个简单的事件处理器中(createServer的回调函数中),这将会是一个非常复杂的处理过程。而使用中间件后会将应用拆分为更小单元(让代码有更强大的表达能力),还能够实现很好的重用性。
  如之前用HTTP方式所写的应用,使用中间件模式可以写成这样(当然这里也仍然需要到Connect模块啦) server-http.js:

/**
 * 模块依赖
 */
var connect = require('connect');
var fs = require('fs');
var serve =
/**
 * 根据文件路径来获取文件内容,并添加'Content-Type'头信息
 * @param  {[type]} path 文件路径
 * @param  {[type]} type Content-Type头信息
 * @return {[type]}      [description]
 */
function (res, fs, path, type) {
    res.writeHead(200, {'Content-Type': type});
    fs.createReadStream(path).pipe(res);
};

/**
 * 创建服务器
 */
var server = connect.createServer();

server.use(function(req, res, next) {
// 检查URL是否和服务器目录下的文件匹配,如果匹配,则读取该文件并展示出来
    // 请求.jpg图片
    if('GET' == req.method 
        && '/images' == req.url.substr(0, 7) 
        && '.jpg' == req.url.substr(-4)) {
        // 返回对应图片
        // ...
        fs.stat(__dirname + req.url, function(err, stat) {
            // 如果检查文件是否存在时发生错误,则终止进程并发送HTTP 404状态码告知无法找到请求的图片。
            // 对于stat成功但是路径所表示的并非是文件时,也要做此处理。
            if(err || !stat.isFile()) {
                res.writeHead(404);
                res.end('Not Found');
                return;
            }

            // 发送图片资源
            serve(res, __dirname + '/website' + req.url, 'application/jpg');
        });

    } else {
        // 交给其他的中间件去处理
        next();
    }
});

server.use(function(req, res, next) {
    if('GET' == req.method && '/' == req.url) {
        // 发送html文件,默认请求index.html
        // ...
        // console.log(__dirname);
        serve(res, __dirname + '/website/index.html', 'text/html');
    } else {
        // 交给其他的中间件去处理
        next();
    }
});

server.use(function(req, res, next) {
    // 处理其他请求,返回404错误码
    res.writeHead(404);
    res.end('Not found');
});

server.listen(3000);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Node中的Connect 的相关文章

  • axios 的理解和使用 axios.create(对axios请求进行二次封装) 拦截器 取消请求(axios.CancelToken)

    目录 axios是什么 axios特点 axios中文文档 axios常用语法 axios安装 axios简单使用 默认get请求 post put delete axios难点语法 axios create config 对axios请求
  • 仿叮咚买菜开源代码

    1 预览 1 前台 http dingdong nodebook top github地址 https github com cgq001 dingdong 2 后台管理 http dingdong admin nodebook top g
  • 如何在 MacOS 上安装 Node.js

    Node js 是一个强大的 JavaScript 运行时环境 允许您在服务器端执行 JavaScript 它广泛用于开发可扩展的 Web 应用程序 命令行工具等 在本文中 我们将介绍在 macOS 系统上安装 Node js 的过程 先决
  • 在node中使用模板引擎---art-template

    art template是一个简约 超快的模板引擎 它不仅可以使用在浏览器中 也可以使用在node中 模板引擎最早是使用于服务器端 后来才发展到了前端 首先是它的安装 我们可以在官方文档中看到 它的安装只需要一行命令 为了方便 下面是官网文
  • Async详解之一:流程控制

    转载 http freewind me blog 20120515 917 html 为了适应异步编程 减少回调的嵌套 我尝试了很多库 最终觉得还是async最靠谱 地址 https github com caolan async Asyn
  • npm start 作用

    在配置phonecat项目时需要运行npm start在本地配置一个服务器环境 npm start首先会安装一系列的必要程序 这些程序依赖package json中的内容 package json中的内容详解如下 依赖包介绍 在克隆项目之后
  • node request 解决请求时 有时候 content-length 获取不到

    今天使用了 request 模块的时候 想获取每次请求的大小 以方便判断下载进度 网速等等 然后 content length 头总是获取不到 下面给出解决方法 request 模块的使用方法见 api 文档 https github co
  • 在node中使用es7

    今天学写了体验异步的终极解决方案 ES7的Async Await这篇文章 发现作者是用 es7 的语法写 node 所以顺便学习了一下如何在 node 中使用 es7 的语法 记录一下 首先安装 babel cli yarn add bab
  • npm指令执行前执行自定义代码

    1 基本逻辑 npm start执行前执行node bin wb handle scripts wb node bin wb handle npm start wb handle源码 删除deleteNodeModules配置的最后一级目录
  • js __proto__、prototype 、constructor 三者关系总结

    一 proto 属性 proto 怎么读 杠杠 proto 杠杠 proto 读作 dunder proto double underscore proto 的缩写 并且它前后两边 分别是 两个 下划线 由 proto 属性来连接对象 直到
  • jsoup的Elements类

    随时随地阅读更多技术实战干货 获取项目源码 学习资料 请关注源代码社区公众号 ydmsq666 一 简介 该类是位于select包下 直接继承自Object 所有实现的接口有Cloneable Iterable
  • 使用Koa2进行Web开发(二)静态文件与路由

    静态文件处理 这里选择koa static作为处理静态文件的中间件 const Koa require koa const app new Koa const serve require koa static app use serve d
  • 了解 node周边生态

    前言 Node js 周边的生态非常强大 NPM Node包管理 上有超过60万个模块 日下超过载量3亿次 但对新人和其它语言背景的开发者来说 了解node周边生态不是一件容易的事 在入门之前需要弄懂不少复杂的概念 废话不多说 来看看本次分
  • 【node】12、Koa实现简单爬虫案例

    效果图如下 首先我们新建文件夹 进入终端 初始化node项目 npm init y 安装koa搭建服务模块 npm install koa 安装superagent发送请求模块 npm install superagent 安装cheeri
  • Node之使用dns模块解析域名

    引 在网络编程中 开发者更倾向于使用域名 而不是IP地址来指定网络连接的目标地址 在Node js中 提供dns模块 以实现域名查找及域名解析的处理 在dns模块中 提供了三个主方法及一系列便捷方法 其中三个主方法分别为用于将一个域名解析为
  • Node.js爬虫实战:搜狗图片爬取

    说在前面 当我们在网上寻找图片时 经常会遇到需要批量下载搜索结果中的图片的情况 而搜狗作为中国颇具影响力的搜索引擎之一 其图片搜索功能提供了丰富多样的图片资源 在这种情况下 我们希望能够通过编程的方式 批量下载搜狗图片搜索结果中的图片 以便
  • Node.js 工作线程与子进程:应该使用哪一个

    Node js 工作线程与子进程 应该使用哪一个 并行处理在计算密集型应用程序中起着至关重要的作用 例如 考虑一个确定给定数字是否为素数的应用程序 如果我们熟悉素数 我们就会知道必须从 1 遍历到该数的平方根才能确定它是否是素数 而这通常非
  • 当我通过 socket.io 操作会话时,如何避免 node.js 中的竞争条件?

    我在我的 socket io 设置中使用这个授权函数 io set authorization function data accept if data headers cookie return accept Session cookie
  • 如何在 MATLAB 中对连接的点进行聚类?

    想象一下 我们有很多点 其中一些点连接在一起 我们想要将它们聚类 请看下图 如果我们有 连接矩阵 点 我们如何将它们聚类为两组 连接点组 ConnectivityMatrix 1 2 1 3 2 4 2 3 2 1 3 1 3 2 3 4
  • 使用 Git 的 Spring Cloud 配置服务器 - 无法克隆或签出存储库连接超时

    我正在使用 GIT 在 Spring Cloud Config Server 上进行 POC Spring Boot 1 5 3 RELEASE 爪哇1 8 弹簧工具套件https github com kishornpatil https

随机推荐

  • mysql中的null值和空值区别

    转载自 xff1a 点击打开链接 标签 xff1a 笔记 mysql null 发表时间 xff1a 2014 06 06 23 46 作者 xff1a 出处 xff1a http jackyrong iteye com mysql中的nu
  • bootstrap-table的入门使用——从服务器获取数据

    参考 xff1a Bootstrap Table 查询 xff08 服务器端 xff09 刷新数据 这里需要使用 bootstrap table 插件 使用了CSS3loader显示加载过程 效果如下 xff1a index html lt
  • MySql中UTF8 和 GBK 编码中文字符长度问题

    转载自 xff1a MySql中UTF8 和 GBK 编码中文字符长度问题 MySql中UTF8 和 GBK 编码中文字符长度问题 出处 xff1a http blog csdn net 为什么要了解MySql中UTF8 和 GBK 编码中
  • PHP对表单提交特殊字符的过滤和处理

    转载自 xff1a PHP对表单提交特殊字符的过滤和处理 函数名 释义 介绍htmlspecialchars将与 单双引号 大于和小于号化成HTML格式 amp 转成 amp amp 34 转成 amp quot 39 转成 amp 039
  • ThinkPHP中数据库操作返回值总结

    转载自 xff1a ThinkPHP中数据库操作返回值总结 关键字 xff1a Thinkphp 返回值 数据库操作 select返回值 add返回值 setDec返回值 Thinkphp中的Think Model类提供了数据库的基本CUR
  • 基于 Token 的身份验证

    转载自 xff1a 基于 Token 的身份验证 最近了解下基于 Token 的身份验证 xff0c 跟大伙分享下 很多大型网站也都在用 xff0c 比如 Facebook xff0c Twitter xff0c Google 43 xff
  • 打造 Bootstrap Tags Input 同 Modal 结合的利器

    Boostrap Tags input 的使用 xff1a http bootstrap tagsinput github io bootstrap tagsinput examples Boostrap Tags Input 插件基于Bo
  • 打造 Bootstrap Tags Input 同 Modal 结合的利器(改)

    对上文 打造 Bootstrap Tags Input 同 Modal 结合的利器 中的 js 进行整合 xff0c 如下 xff1a bootstrap tagsinput demo js Created by DreamBoy on 2
  • 我的简单PHP框架——LabPHP v1.0.1

    此前讲到 我做的一个基于MVC设计思想的简单PHP框架 xff08 我的简单PHP框架 LabPHP xff09 xff0c 这里对其进行一些改进 xff0c 改进地方如下 xff1a 1 对 LabPHP Common functions
  • 关于ThinkPHP中URL及模板文件名大小写的讨论

    参考 xff1a ThinkPHP3 2 3完全开发手册 URL模式 thinkphp中处理url大小写敏感的技术方案 TP模板因路径大小写获取不到的Bug 特别地 xff0c 需要注意的是 xff1a 调试模式下URL区分大小写 xff1
  • 【免费送书】说说哪本书曾经让你爱不释手

    编程狗在线 自由的编程学习平台 一本好书带给人的不止于知识收获 xff0c 还会对你的成长有所帮助 xff0c 与你的每次经历产生共鸣 每天读一点 xff0c 坚持不懈 xff0c 你就能成为专业高手 如果你能每两个月读一本好的编程书 xf
  • PHP中的cURL函数

    今天看了一个接口的使用 xff0c 其中接口的示例中使用到PHP的cURL函数 xff0c 那么有趣的事情就来了 使用PHP向某个URL发送数据并接收响应数据 xff1a function request data url data 61
  • 设计模式之适配器(Adapter)模式

    转载自 xff1a 设计模式学习笔记 适配器 Adapter 模式 参考 xff1a Java设计模式之Adapter模式 2 自己阅读了原文中的例子颇有受益 xff0c 在此前常听到Java中adapter适配器一词 xff08 虽说现在
  • Java软件体系结构设计模式之结构模式 知识点摘录

    以下知识点摘录自 xff1a Java软件体系结构设计模式标准指南 一书 其中可能包含本人的一些感悟 Java软件体系结构设计模式之结构模式 xff08 11种 xff09 结构模式主要用来 xff1a 1 xff09 处理把责任委托给其他
  • 支付宝在线支付接口开发教程与总结

    转载自 xff1a 支付宝在线支付接口开发教程与总结 1 什么是第三方支付 所谓第三方支付 xff0c 就是一些和各大银行签约 并具备一定实力和信誉保障的第三方独立机构提供的交易支持平台 在通过第三方支付平台的交易中 xff0c 买方选购商
  • Android 应用商店评分+APP分享

    转载自 xff1a Android Market链接的生成 调用Market 搜索软件 Android 调用已安装市场 xff0c 进行软件评分的功能实现 参考 xff1a Android跳转到应用商店的APP详情页面 xff0c 以及 G
  • 用一个二维码做下载地址,自动区分是 ios 还是 android

    转载自 xff1a 用一个二维码做下载地址 xff0c 自动区分是 ios 还是 android 更多参考 xff1a 好推二维码如何通过应用宝微下载支持微信自动打开APP下载 xff1f 用一个二维码做下载地址 xff0c 自动区分是 i
  • Node中的JavaScript

    Node中的JavaScript global对象 在浏览器中 xff0c 全局对象指的就是window对象 xff1b Node中有两个类似却各自代表着不同含义的对象 xff1a global和process xff1b 任何global
  • Node中的HTTP

    来自对 了不起的Node js 一书的学习 HTTP协议 超文本传输协议 xff0c 又称为HTTP xff0c 是一种Web协议 HTTP协议构建在请求和响应的概念上 xff0c 对应在Node js中就是由http ClientRequ
  • Node中的Connect

    来自对 了不起的Node js 一书的学习 Connect Node js为常规的网络应用提供了基本的API 然而 xff0c 实际情况下 xff0c 绝大部分网络应用都需要完成一系列类似的操作 xff0c 这些类似的操作你一定不想每次都重