遗留问题
在上一节课的作业中,我们一定遇到了一点问题——虽然将页面内容正确的返回给了浏览器,但是浏览器显示的样式却是不正确的,这是因为在HTML的\标签中我们这样引入了CSS资源:
<link rel="stylesheet" href="css/footer.css"/>
那么浏览器会如何去获取这个资源呢?假设当前访问的URL是http://localhost:8080/posts/create
,那么CSS资源就是该URL的相对路径——http://localhost:8080/posts/css/footer.css
,我们的应用中并没有配置或声明如何处理这个URL,所以自然也就会得到404 Not Found
的返回码。
外部资源文件
在编写HTML代码的过程中,我们会遇到几类外部资源:
- CSS文件:\
- JavaScript文件:\
- 图像:\
在之前的课程学习里,这些外部资源都是通过HTTP协议访问得到——也就是说,当我们用浏览器打开我们编写的HTML页面(无论是通过本地文件直接打开,还是访问Spring Boot服务器),在获取页面内容本身之外,还需要像外部服务器(例如maxcdn.bootstrapcdn.com)发起HTTP请求以获取我们需要的CSS/JavaScript资源。
但是在我们开发过程中,如果某个时刻不能访问Internet,那我们的页面也就无法正确的展现出它应有的样式。另一方面,除了使用第三方库,我们自己还会编写大量的CSS/JavaScript文件,这就要求我们必须有一种很快的方式能够在修改之后立马在本地看到结果。
本地资源文件
首先我们抛开本地HTTP服务器,简单来看在本地编写一个HTML文件以及使用CSS资源,那么我们可以这样组织项目结构:
.
├── index.html
├── css
└── style.css
└── js
└── main.js
在index.html文件中可以这样引用它们:
<link rel="stylesheet" href="css/style.css"/>
<script src="js/main.js"></script>
css/style.css和js/main.js都是使用相对路径描述,当我们在浏览器中打开index.html,URL应该类似file:///Users/luoruici/app/index.html,此时当浏览器解释到上述引用外部资源的代码,会以当前访问的URL为基准,根据相对路径计算出完整的HTTP请求地址:
Base: file:///Users/luoruici/app/index.html
CSS: file:///Users/luoruici/app/css/style.css
JavaScript: file:///Users/luoruici/app/js/main.js
服务器中的静态资源文件
如果我们需要讲index.html
放在服务器中呢?index.html
位于templates
目录下,通过http://localhost:8080/可以访问首页内容,但是CSS和JavaScript外部资源呢?因为我们的HTTP服务器根本没有处理它们,所以不可能通过类似http://localhost:8080/css/style.css这样的方式来访问它们使得我们的页面正确显示。
所以,在这一节中我们将学习如何处理这些静态资源文件。默认情况下,Spring Boot会将类路径上的/static/
目录的内容Serve起来,意思就是所有访问http://localhost:8080/static/**
的请求,都会返回/static/
目录中对应路径的文件内容,于是我们可以这样组织文件目录结构来处理静态资源(以下是src/main/resources
目录结构,这个目录经过编译后会被添加到类路径上):
.
├── static
├── css
└── style.css
└── js
└── main.js
└── templates
└── index.html
这样,当我们经过以上布局,重启应用后,就可以通过访问http://localhost:8080/css/style.css
和http://localhost:8080/js/main.js
来获取CSS和JavaScript资源了。
在HTML中引入资源
之前在index.html
中我们这样引入CSS和JavsScript资源:
<link rel="stylesheet" href="css/style.css"/>
<script src="js/main.js"></script>
现在如果不修改它我们直接访问http://localhost:8080
,css和js文件都被正确加载了。但是这样真的正确吗?实际上,当我们访问根路径时,之前提到的相对路径计算的结果却是恰好就是正确的访问地址。但是如果我们访问的路径是/123/456/789.html
呢?根据相对路径规则得到的结果就会完全错误了。在Web开发中,我们往往需要一种介于相对路径和绝对路径之间的资源访问方式——Context路径:
<link rel="stylesheet" href="/css/style.css"/>
<script src="/js/main.js"></script>
这里只是简单的在URL的最前面加上了/,但是意义和相对路径就完全不同了,此时服务器会将其视为访问当前host中的“绝对路径”——也就是自动在这个路径之前添加上协议、主机名和端口(都是当前服务器的相同信息),那么无论我们访问的是当前网站下的任何路径,它都会给出统一的结果。