Express static 托管静态文件 理解
今天偶尔看了一下服务端渲染,遇到了express.static, 在以前学习webpack配置服务端渲染时,也使用express.static 中间件,两者配置不太一样,由于当时也没有认真学,所以 一时之间非常困惑,不知道它是怎么正确使用。看了Express 官网,介绍的也是非常简单,还是不太懂,就查了一些资料,算是有一点懵懂的认识。
首先要认识一点,在服务器上,一切都是资源, 我们发出的任何请求,都是请求资源。当我们在浏览器中输入www.baidu.com的时候,我们是向www.baidu.com服务器请求index.html资源,发送的请求是get请求。页面中可能会有css, img, js等文件,当html 文件在进行解析的时候,它碰到css, img, js时,就会向服务器发送请求,请求这些资源,这些请求也是get 请求。我们平时写js 代码,发送ajax 请求, 它请求的也是资源,只不过通常是json 字符串或xml。 在web 的领域,一切请求全都是为了资源,资源也可以任意的形式,文本文件,图片文件, 字符片段等等。只要明白了这一点,理解静态文件服务就相对轻松了。
现在用express 搭建一个服务器,来实战理解一下express.static 托管静态资源。新建一个目录,就叫express-static吧。 npm init -y 快速创建package.json文件,npm install express --save 安装express 依赖。新建server.js,来写服务器代码. 我们先按照Express的官网的要求使用express.static中间件。那就要再新建一个public文件夹,在里面建index.html 文件,和css 文件。整个目录结构如下:

index.html 中随便写点什么,我们就写一个h1好了,还要引入css, 文件如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<h1>express.static 托管静态资源</h1>
</body>
</html>
css也简单点,直接给h1 一个color 就可以了,
h1 {
color: red;
}
现在来写server.js 服务端代码,文件也很简单,只使用了express.static中间件。它接受一个参数,就是静态资源文件所在的目录,在这里是public目录,直接把public传递给它就可以了,按照官网的说法,只要这样配置,服务器就可以提供静态文件访问了。nodemon server.js 启动服务器试一下。
var express = require('express');
var path = require('path');
var app = express();
// 利用express.static中间件来托管静态资源。
app.use(express.static(path.join(__dirname, 'public')));
app.listen(5000, () => {
console.log('start: 5000')
})
服务器启动后,打开浏览器,输入localhost:5000, 它确定显示了index.html的内容,并且也应用到了css 样式,确实是访问到了静态文件html, css.

刚才在上面说了,当我们在浏览器地址栏中,输入网址时,它是在请求资源index.html,html在解析的过程中碰到css, 它也是在请求资源,css文件,我们来看一下是不是这样,这样用到浏览器控制台中的NetWork 板块。打开控制台,找到Network版块

可以看到,它确实是发送了两个请求,一个是localhost, 一个是style.css,和我们预想的一样。点击localhost 的看一下具体的内容

发送的url : http://localhost:5000/, 请求方式是Get 请求。点到图中的Preview 或Response看一下, 返回的是index.html 文件
现在可以再来看一下style.css

它请求的地址是 http://localhost:5000/style.css,我们在index.html中写的是 href='./style.css' 相对路径,但在真实的请求中,它是向服务器根目录请求的资源。当然方法还是get 请求。Response是我们写的css 文件。
静态文件的访问请求,服务器确实是帮我们处理好了,这肯定是我们express.static的功劳。我们把express.static的那段代码注释掉就知道了。注释掉代码,
// 利用express.static中间件来托管静态资源。
// app.use(express.static(path.join(__dirname, 'public')));
然后刷新一下浏览器, 任何资源都访问不到。

看一下控制台的Network, 404 not found, 也就是说,服务器没有处理这个请求的代码

我们知道,它这里其实是发送了一个get 请求,请求的地址是http://localhost: 5000, 根据这个请求内容,我们可以自己写一个处理请求,其实它就是路由,get 请求用到的是app.get, 由于这里的请求是服务器根地址,所以路径是'/', 响应就是index.html文件,这里用到是sendfile 来发送文件, 代码如下:
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public/index.html'))
})
这时刷新浏览器,可以看到页面显示文字了,但是字体颜色是黑色,样式有问题

这时再看控制台, localhost 请求成功了,style.css 是红色的,状态是404 not found, 也就是没有找到资源

这时我们已经知道了, 浏览器向服务器请求了css 资源,但是在服务端并没有处理这个请求,所以就报404的错误,这时和处理html 一样,我们要写一个路由,来处理css请求,这里还是get请求,所以app.get, 因为请求的是所有的css文件,请求的处理路径要写成’*.css’, 文件的发送还是用sendFile.
app.get('*.css', (req, res) => {
res.sendFile(path.join(__dirname, 'public/style.css'))
})
这时再刷新浏览器,可以看到颜色变红了,打开控制台,style.css也请求成功了,这时我们没有使用express.static 静态服务中间件, 而是自已写的路由,你会发现作用是一样的。我们的页面中还没有js, image 等资源,如果有的话,我们还需要写处理js文件和图片文件的路由,分别对应js 和image 文件的请求。
到这里就明白了,html,js, css, image 都是存放在服务端的资源,当在浏览器中输入网址的后,我们就是向服务器请求这些资源,相对应的服务端就要有对应的路由来处理这些请求,否则就是404 not found 错误。对于这些静态文件的路由处理,代码逻辑都是一致的,就是返回请求的文件。再往大处想一想,我们每写一个网站的服务端,都要处理这些静态文件的请求, 因为几乎所有的html文件是都包括js, css, image 文件, 是不是太麻烦了,我们可以复制粘贴,但也是不太好,最好的办法,当然是把这些一致的处理逻辑抽离出来,形成一个单独的组件,直接使用组件就好了,这就是express.static 中间件的由来,它就是处理js, css, image等静态文件的请求,它把我们对静态文件的路由处理封装起来。 它的参数是一个文件夹,就是当有请求过来的时候,直接到该文件来下寻找资源,如果有,就直接返回文件,程序不再向下执行,如果找不到,程序再向下执行。那我们直接把静态文件放到该文件夹,就不用写这些静态文件的路由了。
这里还要注意一点,express.static 中间件的使用,要放到其它处理请求逻辑的前面, 因为页面在渲染的过程中首先请求的就是html, css, js 文件。如果有的其它请求处理这些静态文件的请求,那就不会返回静态文件了。我们写一个匹配任意请求的文件,app.get(‘*’), 而且把它放到express.static 中间件的前面, 试一试, 整个server.js 如下:
var express = require('express');
var path = require('path');
var app = express();
// 匹配任意请求*, 并且放到express.static 静态服务器的前面。
app.get('*', (req, res) => {
res.send('Hello word');
})
app.use(express.static(path.join(__dirname, 'public')));
app.listen(5000, () => {
console.log('start: 5000')
})
这时再刷新浏览器, 只看到了hello world.

打开控制台的Network, 你会发现 Respone 返回的hello world 字符串,而不是html 文件, 因为app.get(‘*’) 把我们静态文件的请求给拦截了,并返回了。路由的处理就是有一个匹配就返回,我们的express.static本质上也是一个路由,所以轮不到它进行执行了。
在express的官网,express.static 还有一种使用情况, 就是两个参数,第一个参数是一个路径,第二个参数才是express.static 的使用。
app.use('/static', express.static('public'));
第一个参数路径,表示的是我们的静态文件的引入路径的前面有一个路径/static ,比如,我们的index.html中引入css 改成如下方式
<link rel="stylesheet" href=" /static/style.css">
css 的资源请求的路径前面肯定会再一个static目录,http://localhost:5000/static/style.css,因为前端资源请求前面有static路径, 所以我们静态文件的路由处理,前面也要加static路径进行匹配。
var express = require('express');
var path = require('path');
var app = express();
// 因为前端资源请求前面有static路径, 所以我们静态文件的路由处理,前面也要加static路径进行匹配。
app.use('/static', express.static(path.join(__dirname, 'public')));
// 为了处理html 文件的请求。
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public/index.html'))
})
app.listen(5000, () => {
console.log('start: 5000')
})
这时再刷新浏览器,没有问题,打开控制台,也没有问题。
Express static 托管静态文件 理解的更多相关文章
- Express之托管静态文件
中间件express.static 我们使用express初始化一个目录的时候,会在app.js中看到一大推的app.use. 其中一个主要的中间件是express.static(4.0版本依旧保留的 ...
- Express 学习笔记纯干货(Routing、Middleware、托管静态文件、view engine 等等)
原始文章链接:http://www.lovebxm.com/2017/07/14/express-primer/ 1. Express 简介 Express 是基于 Node.js 平台,快速.开放. ...
- 利用 Express 托管静态文件
通过 Express 内置的 express.static 可以方便地托管静态文件,例如图片.CSS.JavaScript 文件等. 将静态资源文件所在的目录作为参数传递给 express.stati ...
- 利用express托管静态文件
通过express内置的express.static可以方便的托管静态文件,例如图片.css.javascript文件等. 将静态资源文件所在的目录作为参数传递给express.static中间件就可 ...
- Express (Routing、Middleware、托管静态文件、view engine 等等)
1. Express 简介 Express 是基于 Node.js 平台,快速.开放.极简的 web 开发框架,它提供一系列强大的特性,帮助你创建各种 Web 和移动设备应用. Express 不对 ...
- (三)、Express 路由、静态文件、
一.路由 路由(Routing)是由一个 URI(或者叫路径)和一个特定的 HTTP 方法(GET.POST 等)组成的,涉及到应用如何响应客户端对某个网站节点的访问. 每一个路由都可以有一个或者多个 ...
- 在express中提供静态文件笔记
在express中提供静态文件 要在express框架中提供静态文件,如:css.javascript等文件,就要使用到他的内置中间件功能express.static,将包含静态文件目录文件传递给ex ...
- app.use(express.static)设置静态文件目录小解
app.use(path, function, [, function]) 功能: 为path注册中间函数,即根据path使用不同函数进行处理,默认path是"/",也就是处理任何 ...
- express中放置静态文件
不使用模版引擎的话要直接添加html,可以使用express.static()中间件设定静态文件目录,然后将html文件放在里面,如:express默认静态文件目录为 app.use(express. ...
随机推荐
- Java NIO6:选择器1——理论篇
一.选择器 选择器提供选择执行已经就绪的任务的能力,这使得多元I/O成为了可能,就绪执行和多元选择使得单线程能够有效地同时管理多个I/O通道. 某种程度上来说,理解选择器比理解缓冲区和通道类更困难一些 ...
- Java内存模型与线程安全
原文链接:blog.edreamoon.com Java内存模型 计算机cpu的运算能力强大,但是数据的存储相对于cpu运算能力需要消耗大量时间,为了充分利用运算能力引入了缓存,但是也为计算机系统带来 ...
- 【转】AlphaGO Zero 原理
原文地址:https://www.hhyz.me/2018/08/08/2018-08-08-AlphaGO-Zero/> 1. 概述 简单来说,AlphaGo Zero 的训练可以分为三个 ...
- mybatis百科-结果集映射类ResultMap
目录 1 成员变量 2 构造函数 3 其他函数 3.1 setter 和 getter 函数 4 静态内部类 4.1 成员变量 4.2 构造函数 4.3 建造者相关的函数 4.4 获取配置的构造方法参 ...
- Git简易的命令入门
Git 全局设置: git config --global user.name "kszsa" git config --global user.email "duyon ...
- 设计模式——MVC MVP MVVM
了解到Vue是MVVM前端框架, 中午就研究了一下MVVM,但要从MVC开始说起: M(Model):模型,提供数据: V(View):视图,负责显示: C(Controller):控制器,负责逻辑处 ...
- 1171: lfx捧杯稳啦!
escription Lfx在复习离散的时候突然想到了一个算法题,毕竟是lfx, 算法题如下: 他想知道这样的问题,先定义1~n中即是3的倍数,又是11的倍数的那些数的和sum, 他想知道sum有多少 ...
- Array and Segments (Easy version) CodeForces - 1108E1 (暴力枚举)
The only difference between easy and hard versions is a number of elements in the array. You are giv ...
- R语言
什么是R语言编程? R语言是一种用于统计分析和为此目的创建图形的编程语言.不是数据类型,它具有用于计算的数据对象.它用于数据挖掘,回归分析,概率估计等领域,使用其中可用的许多软件包. R语言中的不同数 ...
- Django 生成验证码或二维码 pillow模块
一.安装PIL PIL:Python Imaging Library,已经是Python平台事实上的图像处理标准库了.PIL功能非常强大,API也非常简单易用. PIL模块只支持到Python 2 ...