在搭建好图床后,我的创作流程是这样的:先截图–>通过PicGo手动上传到对应的图床–>复制markdown格式的链接到我的Typora中,总觉得哪里怪怪的。

直到我偶然间发现Typora是支持自动上传而且返回url的,有点爽,确实好方便,今天来分享下,肯定还有很多跟我一样不知道的。

在Typora的偏好设置中:

image-20231211161451734

打开自动上传图片的功能:

image-20231211161633003

然后在上传服务里绑定PicGo即可。

这样你以后在创作时:直接截图–>图片复制到Typora即可,省去了上传和复制markdown链接的步骤。

上传服务里还可以绑定其他图床,摆脱对PicGo的依赖,后面我会研究一下Custom Command的玩法。

上一篇:搭建图床加速你的静态网站

前几天用GitHub加NetLify加PicGo搭建了一个图床,对于一般需求当然是够用了,但是考虑到我的博客首页有大量的随机背景图,决定用OSS尝试一下,发现国内确实性能更好一些,打开速度相比之前能加速一秒左右,更重要的是,偶尔出现十几秒还进不去的情况变少了,稳定性得到了很大的加强。

下面简单介绍一下步骤:

1.打开阿里云官网选择对象存储OSS。

2.首次使用需要开通,开通完可以免费试用三个月:

3.前往OSS控制台,新建一个OSS Bucket:

读写权限改为公共读,地域选择离你比较近的:

4.点击右上角头像访问控制:

创建一个用户:

创建完之后要记下要记下AccessKey ID 和 AccessKey Secret,之后配置PicGo用到,因为这个界面关掉之后就不好找了,所以最好记在记事本里。

然后给用户添加权限:

选择管理对象存储服务权限即可。

这里阿里云这边就弄好了,有需求的可以研究一下防盗链的设置。

5.回到客户端,配置阿里云OSS:

配置名随便取,keyid 就是创建用户的AccessKey ID,KeySecret 就是AccessKey Secret,设定Bucket就是创建Bucket的名字,存储区域就是oss-cn-地域的格式。

如果绑定域名可以填写自定义域名,其他不用填写。

至此,不出问题的话,你就可以愉快的上传和下载了。

对于一个博客来说,先不考虑文章写的水平如何,我们首先考虑的应该是网站的性能,其次才是其样式,主题,特效,在保证优秀的性能的前提下,才可以适当添加一些样式来增添网站的美观度。

我们知道对于同一个网站,移动端的加载速度总是稍慢于pc端,而网站的压力越大 ,移动端落后的就越明显,这是由于浏览器的性能和设备的性能导致的。

都以为现在手机性能都很强大了,但是当我拿起我的那台火龙888,我才发现,打开一个小小的博客网站都能让我的破手机变烫,而且还时不时进不去,这让我很烦,所以我决定进而优化我的博客。

除了性能问题,我还想说手机上的特效大多数是不必要的,因为在6寸多的小屏幕上加载点击特效,背景特效这些显得很臃肿,反而显得不好看,博客在移动端的主题还是要以简约为主。

我决定关闭一些不必要的特效在手机上,但是我又想让这些特效在电脑上正常加载。

实现这些其实有很多方法,不同的主题也有不同的方案,但是有一个通用的方案,就是识别设备的宽度,如果宽度大于某个值,就视为pc,低于这个值就视为手机,然后加载对应的资源。

1. 下面是一个EJS模板:

找到你的layout.ejs文件,你可以在<head></head>标签内添加下面代码,当然你需要自己定制它的功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
// 在浏览器端执行的 JavaScript 代码
document.addEventListener('DOMContentLoaded', function () {
// 获取设备宽度
var deviceWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;

// 根据设备宽度判断加载资源
if (deviceWidth >= 768) {
// 在电脑端加载特效
var scriptElement = document.createElement('script');
scriptElement.src = '/js/your-file.js';
document.head.appendChild(scriptElement);

var linkElement = document.createElement('link');
linkElement.rel = 'stylesheet';
linkElement.href = '/css/your-file.css';
document.head.appendChild(linkElement);

// 其他资源和特效
}
});
</script>

在这个模板中:

1
document.addEventListener('DOMContentLoaded', function () {
  • document.addEventListener: 注册一个事件监听器,用于在文档加载完成后执行指定的函数。

  • 'DOMContentLoaded': 事件类型,表示文档的 DOM 内容已经加载完成,不包括样式表、图像等外部资源。

  • function () { ... }: 事件发生时要执行的回调函数。


1
var deviceWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
  • window.innerWidth: 获取浏览器窗口的内部宽度。

  • document.documentElement.clientWidth: 获取文档元素(通常是 <html> 元素)的客户端宽度。

  • document.body.clientWidth: 获取 <body> 元素的客户端宽度。

  • 这一行代码将设备的宽度赋值给变量 deviceWidth。


1
if (deviceWidth >= 768) {
  • 条件判断:如果设备宽度大于等于 768 像素,执行后面的代码块。


1
2
3
var scriptElement = document.createElement('script');
scriptElement.src = '/js/your-file.js';
document.head.appendChild(scriptElement);
  • document.createElement('script'): 创建一个 <script> 元素。

  • scriptElement.src = '/js/your-file.js': 设置该 <script> 元素的 src 属性为指定的 JavaScript 文件路径。

  • document.head.appendChild(scriptElement): 将该 <script> 元素添加到文档头部 (<head>),从而加载并执行指定的 JavaScript 文件。


1
2
3
4
var linkElement = document.createElement('link');
linkElement.rel = 'stylesheet';
linkElement.href = '/css/your-file.css';
document.head.appendChild(linkElement);
  • document.createElement('link'): 创建一个 <link> 元素。

  • linkElement.rel = 'stylesheet': 设置该 <link> 元素的 rel 属性为 ‘stylesheet’,表示这是一个样式表链接。

  • linkElement.href = '/css/your-file.css': 设置该 <link> 元素的 href 属性为指定的 CSS 文件路径。

  • document.head.appendChild(linkElement): 将该 <link> 元素添加到文档头部 (<head>),从而加载并应用指定的 CSS 文件。


1
// 其他资源和特效
  • 在这个部分,你可以根据需要添加其他的资源加载和特效代码,例如创建其他元素、添加样式或执行其他 JavaScript 操作。

2. 举例:动态加载一个鼠标点击烟花特效。

下面这段代码本来是要填入layout.ejs中的

1
2
3
4
5
6
<canvas
id="fireworks"
style="position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; pointer-events: none; z-index: 32767"
></canvas>
<script src="https://cdn.staticfile.org/animejs/3.2.1/anime.min.js"></script>
<script src="/js/fireworks.min.js"></script>

那么我们就可以这样套用这个模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script>
// 在浏览器端执行的 JavaScript 代码
document.addEventListener('DOMContentLoaded', function () {
// 获取设备宽度
var deviceWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;

// 根据设备宽度判断加载资源
if (deviceWidth >= 768) {
// 在电脑端加载特效
var scriptElement1 = document.createElement('script');
scriptElement1.src = "https://cdn.staticfile.org/animejs/3.2.1/anime.min.js";
document.head.appendChild(scriptElement1);
var scriptElement2 = document.createElement('script');
scriptElement2.src = '/js/fireworks.min.js';
document.head.appendChild(scriptElement2);
var fireworksCanvas = document.createElement('canvas');
fireworksCanvas.id = 'fireworks';
fireworksCanvas.style.cssText = 'position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; pointer-events: none; z-index: 32767';
document.body.appendChild(fireworksCanvas);
}
});
</script>

像其他的js,css资源都可以套用上面的模板。

在选择 Hexo 博客的背景图格式时,WebP 是一个备受推崇的选择。WebP 是一种由 Google 开发的先进图像格式,它融合了出色的视觉质量和高度的压缩效率。以下是使用 WebP 格式作为 Hexo 背景图的优势以及相应的 Markdown 代码示例:

WebP 格式的优势

  1. 高压缩率: WebP 格式以其卓越的压缩效率而著称,相较于传统格式,如 JPEG 和 PNG,能够更显著地减小文件大小,提高页面加载速度。
  2. 良好的视觉质量: 尽管进行了强大的压缩,WebP 仍能够保持相对较高的视觉质量,使其成为博客背景图的理想选择。
  3. 支持透明度: WebP 支持 alpha 透明度通道,使其成为既能处理不透明背景又能创建半透明效果的理想选项。

在 Hexo 中使用 WebP 背景图

要在 Hexo 中使用 WebP 格式的背景图,首先需要确保 Hexo 支持 WebP 图片格式。然后,可以使用以下 Markdown 代码示例:

1
background: url('/images/background.webp');

确保你的背景图以 WebP 格式保存,并将其路径正确指向。这样 Hexo 将能够在生成博客页面时正确加载 WebP 格式的背景图。

注意事项

  • 浏览器兼容性: 大多数现代浏览器(如 Chrome、Firefox、Edge)已经支持 WebP 格式,但在使用时仍需确保你的受众大多数使用支持 WebP 的浏览器。
  • 生成 WebP 图片: 你可以使用图像编辑工具或在线转换工具将现有的图片转换为 WebP 格式,确保选择适当的压缩质量以平衡文件大小和视觉效果。

通过选择 WebP 格式作为 Hexo 背景图,你能够实现更快的页面加载速度、优异的视觉质量以及透明效果,提升博客的用户体验。

在现代互联网时代,一个快速、高效的个人博客网站对于吸引读者、提高用户体验至关重要。在本文中,我们将讨论一些关键的优化步骤,帮助你提升你的个人静态博客网站的性能和用户体验。

1. 页面加载速度优化

首要任务是确保你的博客页面加载速度迅速,以吸引并保持读者的兴趣。

  • 压缩和合并文件: 通过压缩和合并CSS、JavaScript以及图片等文件,可以显著减少页面加载时间。
  • 使用CDN: 利用内容分发网络(CDN)提供静态资源,确保全球范围内的读者都能够快速加载你的博客。

2. 响应式设计

确保你的博客在各种设备上都有良好的显示效果,这是提高用户体验的重要因素。

  • 移动友好性: 采用响应式设计,确保你的博客在各种移动设备上都能够良好显示。
  • 优化移动端体验: 确保在小屏幕上,导航、字体和图像等元素都能够适应屏幕尺寸。

3. SEO优化

提高博客在搜索引擎中的排名,使更多读者能够发现你的优质内容。

  • 关键字优化: 在文章标题、描述和正文中合理使用关键字,有助于提高搜索引擎排名。
  • 友好的URL结构: 使用清晰、有意义的URL结构,有助于搜索引擎理解页面内容。

4. 社交分享和评论

增加用户互动,扩大博客的影响力。

  • 社交分享按钮: 添加社交分享按钮,方便读者分享博客内容,提高内容的传播性。
  • 评论系统: 集成一个简单而有效的评论系统,促进读者之间的交流。

5. 安全性优化

保护你的博客和读者的数据安全。

  • 使用HTTPS: 使用HTTPS协议以确保数据传输的安全性。
  • 定期备份: 定期备份博客数据,以防止数据丢失。

6. 内容优化

提供有价值、易读的高质量内容,是保持读者忠诚度的关键。

  • 高质量内容: 确保你的博客内容有深度、有价值,能够吸引并保持读者的兴趣。
  • 定期更新: 定期更新博客,保持内容的新鲜度,让读者期待着回来。

7. 网站分析

深入了解读者行为,以便更好地满足他们的需求。

  • 使用分析工具: 使用工具如Google Analytics等来了解访问者行为,以便进行进一步的优化。
  • 错误监控: 设置错误监控,及时发现并修复可能存在的问题。

通过关注这些优化方向,你将能够提升个人静态博客的整体性能、用户体验和可发现性。优化并保持博客的最佳状态,吸引更多读者,分享更多精彩内容!

我之前一直把本站的所有照片都放在了本站的仓库下,一直觉得搭建图床好像就是节省一下仓库空间,今天我搭建图床之后发现真的有比较明显的加速效果,之前这个博客打开普遍在8秒以上,现在大部分情况下5秒之内就可以打开,我觉得效果很好,所以分享下。

参考的是 Argvchs的教程,我自己懒得再写一遍了,感谢大佬的教程。

他用的是netlify的仓库,速度感觉还可以,只是我比较好奇阿里云OSS的效果怎么样,如果我不满意当前网站的速度,我会出一期OSS图床的教程。


参考教程:搭建图床

以后我打算在这里更新学习经历,一些简单教程以及后面我的一些小项目,然后我会在微信公众号转载我的项目以及一些资源,微信公众号就不更新其他琐碎的教程了,也没人看。其他平台,像知乎,b站之类暂时没有更新知识内容的想法,主要分享一些好玩的内容。(还得看我有没有时间)而gitee,csdn这些主要存放一些零碎资源,例如学校的作业,github就用来存放我的项目。过段时间我打算做一个基于springboot和vue的个人网盘项目,也是因为差不多学完这些,做这个项目来练练手。

由于ParticleX主题是支持放多个背景随机呈现的,只需在配置文件中这样排列(这是yml中的列表):

1
2
3
4
5
6
7
8
9
10
11
background:
- /images/background1.png
- /images/background2.png
- /images/background3.png
- /images/background4.png
- /images/background5.png
- /images/background6.png
- /images/background7.png
- /images/background8.png
- /images/background9.png
- /images/background10.png

然后在Hexo\themes\particlex\source\images目录下存放对应的照片即可:

导言:

在Web应用程序开发中,拦截器是一种重要的技术,用于在请求处理的各个阶段执行自定义逻辑。在Spring Boot中,拦截器提供了一种优雅的方式来处理与请求生命周期相关的事务。本文将深入介绍Spring Boot中的拦截器,包括其作用、使用场景以及如何创建和配置拦截器。

一、拦截器的作用:

拦截器允许我们在请求到达Controller之前和离开Controller之后执行自定义的逻辑。主要作用包括但不限于:

  1. 权限验证: 在请求到达Controller之前验证用户是否有权限访问某个资源。
  2. 日志记录: 记录请求的信息,用于调试和监控。
  3. 跨域处理: 处理跨域请求,设置响应头。
  4. 性能监控: 统计请求处理时间,性能监控等。
  5. 数据统计: 收集请求数据用于统计分析。

二、拦截器的生命周期:

在Spring Boot中,拦截器的生命周期主要包括三个关键方法:

  1. preHandle: 在请求到达Controller之前执行,用于预处理请求。返回true表示继续执行后续处理,返回false表示中断后续处理。
  2. postHandle: 在Controller处理请求后,视图渲染之前执行。可以对ModelAndView进行操作,但无法修改实际的响应内容。
  3. afterCompletion: 在整个请求处理完成并且视图渲染完毕后执行。通常用于释放资源或记录日志。

三、创建和配置拦截器:

以下是创建和配置拦截器的基本步骤:

1. 实现HandlerInterceptor接口:

创建一个类实现HandlerInterceptor接口,并实现preHandle、postHandle和afterCompletion方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MyInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 预处理逻辑
return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 后处理逻辑
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 完成后的逻辑
}
}

2. 配置拦截器:

创建一个配置类实现WebMvcConfigurer接口,覆盖addInterceptors方法,将拦截器注册到应用程序中。

1
2
3
4
5
6
7
8
@Configuration
public class MyInterceptorConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/api/**");
}
}

在上述示例中,MyInterceptor将拦截所有以”/api/“开头的请求。

四、使用场景示例:

下面通过一个简单的使用场景来说明拦截器的应用。假设我们需要在每次请求处理前记录请求日志:

1
2
3
4
5
6
7
8
9
10
11
12
public class LoggingInterceptor implements HandlerInterceptor {

private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.info("Request URL: {}, Method: {}", request.getRequestURL(), request.getMethod());
return true;
}

// ... 其他方法省略 ...
}

在配置类中注册该拦截器:

1
2
3
4
5
6
7
8
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoggingInterceptor()).addPathPatterns("/**");
}
}

这样,每次请求都会在处理前记录请求的URL和请求方法,实现了简单的日志记录功能。

结论:

拦截器是Spring Boot中强大的功能之一,提供了一种灵活而强大的机制,用于在请求处理的不同阶段执行自定义逻辑。通过适当的使用,拦截器可以实现诸如权限验证、日志记录、跨域处理等功能,从而提高Web应用程序的可维护性和可扩展性。

在实际应用中,根据需求选择合适的拦截器,并注意在使用拦截器时要遵循良好的设计原则,以确保代码的清晰性和可维护性。

希望本文能够帮助你更好地理解和使用Spring Boot中的拦截器功能。

在Java Web应用中,过滤器(Filter)是一项重要的技术,用于在请求到达Servlet之前或响应离开Servlet之后执行特定的操作。本文将深入介绍过滤器的概念、作用以及详细的实现方式,包括通过XML配置和注解配置两种方式,以帮助开发者更好地理解和运用这一关键组件。

1. 过滤器的基本概念

过滤器是Java Servlet规范中的一部分,它允许开发者在请求到达Servlet之前或响应离开Servlet之后执行一些操作。过滤器通常用于以下场景:

  • 身份验证和授权: 检查用户是否已登录,是否有权限访问某些资源。
  • 日志记录: 记录请求和响应的相关信息,用于调试和分析。
  • 字符编码处理: 对请求和响应进行字符编码的转换。
  • 性能监控: 统计请求的处理时间,检测潜在的性能问题。

2. 过滤器的生命周期

过滤器具有以下生命周期方法:

  • init(FilterConfig config): 用于进行过滤器的初始化工作,在容器启动时被调用。
  • doFilter(ServletRequest request, ServletResponse response, FilterChain chain): 执行过滤操作的核心方法,可以在此方法中对请求和响应进行处理,并将请求传递给下一个过滤器(或Servlet)。
  • destroy(): 在容器关闭时被调用,用于执行一些资源释放的操作。

3. 过滤器的实现

3.1 编写过滤器类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;

public class MyFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化操作,可获取配置信息
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 在请求处理之前执行的逻辑
System.out.println("Before Request Processing in Filter");

// 执行下一个过滤器(如果有),或者到达Servlet
chain.doFilter(request, response);

// 在请求处理之后执行的逻辑
System.out.println("After Request Processing in Filter");
}

@Override
public void destroy() {
// 资源释放操作
}
}

3.2 通过XML配置过滤器

在web.xml文件中添加如下配置:

1
2
3
4
5
6
7
8
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>com.example.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

3.3 通过注解配置过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

@Bean
public FilterRegistrationBean<MyFilter> myFilter() {
FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new MyFilter());
registrationBean.addUrlPatterns("/*"); // 设置过滤器拦截的路径
return registrationBean;
}
}

4. 过滤器的应用实例

下面演示一个简单的过滤器应用场景,对请求进行身份验证:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class AuthenticationFilter implements Filter {

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;

// 检查用户是否已登录,未登录则重定向到登录页面
if (httpRequest.getSession().getAttribute("user") == null) {
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpResponse.sendRedirect("/login");
return;
}

// 用户已登录,继续执行后续过滤器或Servlet
chain.doFilter(request, response);
}

// 其他生命周期方法和初始化方法的实现
}

通过以上的身份验证过滤器,可以确保只有登录的用户才能访问受保护的资源。

结语

过滤器作为Java Web开发中的重要组件,为开发者提供了在请求处理过程中干预和定制化的能力。通过灵活运用过滤器,开发者可以实现诸如日志记录、身份验证、字符编码处理等功能,从而提升应用的安全性、可维护性和性能。在实际项目中,根据具体需求,合理配置和使用过滤器将对项目的整体质量产生积极影响。

0%