nuxt3+ts+vue3的ssr项目总结

news2024/11/29 14:51:26

目录

一、什么是SSR、SEO、SPA,它们之间的关系又是怎样的。

二、VUE做SSR的几种方法

1、插件prerender-spa-plugin

2、VUE开启SSR渲染模式

3、使用NUXT框架 

三、NUXT3+VUE3+TS

(一)基本配置

1、文件夹介绍

assets

components

pages

api

plugins

utils 

2、布局使用

3、useFetch请求封装

(二)引入element-pluse

1、安装

2、引入

3、使用

(三)引入md文档

1、下载

2、引入

3、使用

用于输入数据

用于回显数据

(四)v-show与v-if踩坑

1、区别

2、问题

(五)el- select与el-tooltip踩坑

1、问题


一、什么是SSR、SEO、SPA,它们之间的关系又是怎样的。

SSR (Server-Side Rendering)服务器端渲染,是一种网页渲染方法,其中服务器在向客户端发送 HTML 之前将页面渲染为完全呈现的 HTML。在 SSR 中,服务器会处理页面的渲染,然后将呈现的 HTML 发送到客户端浏览器,浏览器接收到的是已经包含内容的页面。这有助于搜索引擎更好地索引页面内容,提高首次加载速度,以及有助于 SEO(搜索引擎优化)。

SEO (Search Engine Optimization)搜索引擎优化,是一系列技术和策略,旨在改进网站在搜索引擎结果页面上的排名,以增加网站的曝光度和访问量。在网站的 SEO 中,内容的可索引性、关键词的使用、页面速度和用户体验等都是重要因素。

SPA (Single Page Application)单页面应用,是一种基于 Web 的应用程序,它在加载初始页面后,通过 AJAX 或其他技术在同一个页面上动态加载内容,而不需要完整的页面刷新。SPA 通常在客户端使用 JavaScript 处理页面路由和渲染。SPA 的优点包括更流畅的用户体验,但它可能对搜索引擎索引和首次加载速度产生挑战。

SSR 和 SEO:SSR 通过在服务器端将完全呈现的 HTML 发送到客户端,有助于提高页面在搜索引擎中的可索引性。搜索引擎可以更容易地读取和理解页面内容,从而提高 SEO。相比之下,SPA 在初次加载时可能只有一个空的 HTML 骨架,内容是通过 JavaScript 动态加载的,这可能对 SEO 造成挑战。

SSR 和 SPA:SSR 和 SPA 是两种不同的页面渲染方法。SSR 在服务器端完成渲染,可以提供更好的 SEO 和首次加载性能,但也可能增加服务器负担。SPA 在客户端动态加载内容,提供更流畅的用户体验,但可能面临搜索引擎索引和初始加载速度的问题。一些项目结合两者,使用 SSR 渲染首次加载的内容,然后在后续页面切换时转为 SPA。

想了解更多关于ssr,seo,spa的知识可以看下面这篇文章:

浅谈SPA、SEO、SSR - 简书前后端分离算是最近Web开发的大趋势了,目前已经有大量的公司使用了前后端分离的开发方式。那我们就来大概谈谈前后端分离开发中必须要了解和接触的几个概念:SPA、SEO和SSR。...icon-default.png?t=N7T8https://www.jianshu.com/p/fcb98533bc18

二、VUE做SSR的几种方法

1、插件prerender-spa-plugin

prerender-spa-plugin 是一个用于预渲染单页面应用(SPA)的插件,它可以帮助你在构建时生成静态 HTML 文件,以优化搜索引擎索引和首次加载性能。它需要搭配webpack进行使用,并且改插件有局限性,只能用于较少页面的渲染,一旦渲染的较多负载会非常大,且不适用动态平衡路由的渲染。如商品详情页,文章详情页等等。且该项目已经停止更新了,请谨慎使用。

prerender-spa-plugin官网:GitHub - chrisvfritz/prerender-spa-plugin: Prerenders static HTML in a single-page application.Prerenders static HTML in a single-page application. - GitHub - chrisvfritz/prerender-spa-plugin: Prerenders static HTML in a single-page application.icon-default.png?t=N7T8https://github.com/chrisvfritz/prerender-spa-plugin

这里推荐一篇prerender-spa-plugin详细使用文章:

https://www.cnblogs.com/chuaWeb/p/prerender-plugin.htmlicon-default.png?t=N7T8https://www.cnblogs.com/chuaWeb/p/prerender-plugin.html写的非常详细。


2、VUE开启SSR渲染模式

Vue.js 的服务器端渲染(SSR)通过创建一个服务器入口文件来处理客户端请求,使用 createApp 函数创建 Vue 应用实例并配置路由,根据请求的 URL 匹配路由并预取数据,使用 renderToString 方法将应用渲染为完全呈现的 HTML 字符串,然后将渲染后的 HTML 和状态数据作为响应返回给客户端,客户端接管渲染过的 HTML 并激活应用。从而实现更好的搜索引擎优化、更快的首次加载速度以及服务器和客户端之间更一致的行为。但这个方案也被pass掉了,因为项目过于老,且代码很乱。各种冲突版本兼容问题层出不穷因此也放弃了。但这应该是在节省成本的方法中最适合的一个方案了。

Vue.js 的服务器端渲染(SSR)官网:

Vue.js 服务器端渲染指南 | Vue SSR 指南Vue.js 服务端渲染指南icon-default.png?t=N7T8https://v2.ssr.vuejs.org/zh/这里附带一篇我认为写的较好的博主的文章,大家可以借鉴一下:

如何在vue中实现SSR服务端渲染? - 掘金SSR意为服务端渲染,指由服务侧完成页面的 HTML 结构拼接的页面处理技术,发送到浏览器,然后为其绑定状态与事件,成为完全可icon-default.png?t=N7T8https://juejin.cn/post/7063795725296992270

3、使用NUXT框架 

官网:介绍 · 开始使用Nuxt3 Nuxt中文站Nuxt的目标是使web开发直观和性能与伟大的DX铭记在心。icon-default.png?t=N7T8https://nuxt.com.cn/docs/getting-started/introduction

接下里来我将对NUXT的一些基本使用与踩坑展开描述。

三、NUXT3+VUE3+TS

首先这里默认你已经安装了NUXT3,如果不会的话,请移步至官网文档,就一个命令的事。(注意:node版本要大于16.11.0)

(一)基本配置

1、文件夹介绍

assets

在根目录文件下创建一个名为assets的文件夹用于存储静态文件。如图所示,可以将css文件,图片文件,svg文件包括iconfont字体等文件都存储在这里。

⚠️:这是官方约定俗成的东西。

components

一般用于存储封装好的通用组件。

pages

存放页面的文件夹

 

api

存放网络请求

 

plugins

存放各类插件。

utils 

存放各类工具。

2、布局使用

首先新建一个 layouts 文件夹,写入 default.vue 文件。

 找到 app.vue 文件添加 NuxtLayout 标签。

运行效果:

 

3、useFetch请求封装

首先在根目录下新建一个文件夹 service ,并新建一个文件 index.ts

添加代码如下:

import { UseFetchOptions } from "nuxt/app";


type Methods = "GET" | "POST" | "DELETE" | "PUT";

const BASE_URL = "https://xxx.com/";

export interface IResultData<T> {
  code: number;
  data: T;
  msg: string;
}

class HttpRequest {
  request<T = any>(
    url: string,
    method: Methods,
    data: any,
    options?: UseFetchOptions<T>,
  ) {
    return new Promise((resolve, reject) => {
      const newOptions: UseFetchOptions<T> = {
        baseURL: BASE_URL,
        method: method,
        ...options,
      };

      if (method === "GET" || method === "DELETE") {
        newOptions.params = data;
      }
      if (method === "POST" || method === "PUT") {
        newOptions.body = data;
      }

      useFetch(url, newOptions)
        .then((res) => {
          resolve(res.data);
        })
        .catch((error) => {
          reject(error);
        });
    });
  }

  // 封装常用方法

  get<T = any>(url: string, params?: any, options?: UseFetchOptions<T>) {
    return this.request(url, "GET", params, options);
  }

  post<T = any>(url: string, data: any, options?: UseFetchOptions<T>) {
    return this.request(url, "POST", data, options);
  }

  Put<T = any>(url: string, data: any, options?: UseFetchOptions<T>) {
    return this.request(url, "PUT", data, options);
  }

  Delete<T = any>(url: string, params: any, options?: UseFetchOptions<T>) {
    return this.request(url, "DELETE", params, options);
  }
}

const httpRequest = new HttpRequest();

export default httpRequest;

再在根目录下新建一个 api 文件夹,新建文件index。在这里引入并定义接口,以便于接口的统一处理。

import httpRequest from "~/service";


const getAppdetail = (params: any) => {
    const URL = `/app-server/marketui/${params.marketID}/apps/${params.appID}/detail`
    return httpRequest.get(URL, params);
};

export {
    getAppdetail,
};

使用如下:

<template>
    这是主页面的内容
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { getAppdetail } from '../api/index';
let marketID = ref<string>('859a51f9bb3b48b5bfd222e3bef56425');
let appID = ref<string>('10d2295fc98d4163acc4b2ec9d2917b9');
let getAppdetailData = async () => {
    let Appdetail: any = await getAppdetail({
        marketID: marketID.value,
        appID: appID.value,
    });
    console.log(JSON.parse(JSON.stringify(Appdetail.value)));
};
getAppdetailData()
</script>
<style  scoped>
</style>

请求成功: 

        

(二)引入element-pluse

1、安装

安装element-pluse

npm install element-plus --save

官网文档:

Button 按钮 | Element Plusa Vue 3 based component library for designers and developersicon-default.png?t=N7T8https://element-plus.org/zh-CN/component/button.html 

2、引入

在 根目录创建 plugins 文件夹 ,新建一个名为 element-plus.js 的文件,并添加如下文件内容。

import { defineNuxtPlugin } from '#app'
import ElementPlus from 'element-plus'
import { ID_INJECTION_KEY } from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'

import 'element-plus/dist/index.css'
export default defineNuxtPlugin(nuxtApp => {
    nuxtApp.vueApp.use(ElementPlus, {
        locale: zhCn,
    })
    
    nuxtApp.vueApp.provide(ID_INJECTION_KEY, {
        prefix: 100,
        current: 0,
    })
})

 大功告成就可以使用了。

3、使用

我们更改一下about页面的代码。

运行效果: 

(三)引入md文档

⚠️:此插件使用时需要搭配 <ClientOnly></ClientOnly> 或者 <no-ssr></no-ssr> 使用,否则会报错,因为在服务端获取不到顶级的window对象。 

1、下载

命令

npm install mavon-editor --save

GitHub:

GitHub - hinesboy/mavonEditor: mavonEditor - A markdown editor based on Vue that supports a variety of personalized featuresmavonEditor - A markdown editor based on Vue that supports a variety of personalized features - GitHub - hinesboy/mavonEditor: mavonEditor - A markdown editor based on Vue that supports a variety of personalized featuresicon-default.png?t=N7T8https://github.com/hinesboy/mavonEditor 

2、引入

在 根目录创建 plugins 文件夹 ,新建一个名为 vue-mavon-editor.js 的文件,并添加如下文件内容。

import { defineNuxtPlugin } from '#app'
import mavonEditor from 'mavon-editor'
import "mavon-editor/dist/css/index.css";

export default defineNuxtPlugin( nuxtApp => {
    nuxtApp.vueApp.use(mavonEditor)
})

nuxt.config.ts 中添加如下代码。 

export default defineNuxtConfig({
  //其他配置
  plugins: [
    { src: '@/plugins/vue-mavon-editor.js', ssr: false, mode: 'client' },
  ],
})

3、使用

用于输入数据

这次我们更改 home 文件夹下的 index.vue

<template>
    <h1>这是home页面</h1>
    <ClientOnly>
    <mavon-editor
            ref="md"
            placeholder="请输入文档内容..."
            :boxShadow="false"
            style="z-index:1;border: 1px solid #d9d9d9;height:50vh"
            v-model="value"
            :toolbars="toolbars"
          />
    </ClientOnly>

</template>

<script setup lang="ts">
import { ref } from 'vue';
let value = ref<string>('**这是加粗的文字**');
let toolbars = ref<any>({
    bold: true, // 粗体
    italic: true, // 斜体
    header: true, // 标题
    underline: true, // 下划线
    strikethrough: true, // 中划线
    mark: true, // 标记
    superscript: true, // 上角标
    subscript: true, // 下角标
    quote: true, // 引用
    ol: true, // 有序列表
    ul: true, // 无序列表
    link: true, // 链接
    imagelink: true, // 图片链接
    code: true, // code
    table: true, // 表格
    fullscreen: true, // 全屏编辑
    readmodel: true, // 沉浸式阅读
    htmlcode: true, // 展示html源码
    help: true, // 帮助
    /* 1.3.5 */
    undo: true, // 上一步
    redo: true, // 下一步
    trash: true, // 清空
    save: false, // 保存(触发events中的save事件)
    /* 1.4.2 */
    navigation: true, // 导航目录
    /* 2.1.8 */
    alignleft: true, // 左对齐
    aligncenter: true, // 居中
    alignright: true, // 右对齐
    /* 2.2.1 */
    subfield: true, // 单双栏模式
    preview: true // 预览
  })
</script>
<style  scoped>
</style>

 效果如图:

用于回显数据

<template>
    <h1>这是home页面</h1>
    <ClientOnly>
    <mavon-editor
            ref="md"
            v-highlight class="md" 
            v-model="value" //引入要转换的内容
            :subfield="false"//开启单栏模式       
            :defaultOpen="'preview'" //开启单栏模式
            :toolbarsFlag="false" //开启单栏模式
            :editable="false"//开启单栏模式 
            :scrollStyle="true"//开启滚动条样式
          />
    </ClientOnly>

</template>

<script setup lang="ts">
import { ref } from 'vue';

let value = ref<string>('**这是加粗的文字**');
</script>
<style  scoped>
</style>

(四)v-show与v-if踩坑

1、区别

  1. 渲染方式的区别

    • v-if:当条件为真时,元素会被渲染到DOM中;当条件为假时,元素会被完全从DOM中移除。
    • v-show:无论条件是真还是假,元素都会被渲染到DOM中,但是通过设置元素的display属性来控制是否显示在页面上。
  2. 初始渲染性能

    • v-if:在初始渲染时,如果条件为假,元素不会被添加到DOM中,因此可以提高初始加载性能。
    • v-show:无论条件如何,元素都会被添加到DOM中,只是通过CSS的display属性来控制显示与隐藏,因此初始加载性能上稍逊于v-if
  3. 切换开销

    • v-if:当条件从假切换到真时,会进行DOM插入操作,从真切换到假时,会进行DOM移除操作,可能涉及更多的DOM操作开销。
    • v-show:无论切换条件如何,只需操作CSS属性,因此切换时的性能开销较小。
  4. 适用场景

    • v-if:适合在条件不经常改变的情况下使用,因为它在切换时有更高的开销。
    • v-show:适合在条件需要经常改变的情况下使用,因为它的切换开销较小。

2、问题

使用v-show可能会导致文件加载错误,或者模块渲染失败。比如在这段代码中:

<div class="tag_box" v-if="parentNode">
     <div class="tag_icon">
          <img class="helm_icon" src="../../../assets/svg/tag-type.svg" alt="" />
      </div>
      <div class="tag_name">
           {{ parentNode }}
      </div>
</div>

我的img文件中指向的是静态文件中的一个icon图标。

当我使用v-if时,正常展示。

 当我使用v-show时,展示就出现了问题。

目前不清楚是为何导致的但需要注意这一点。 

(五)el- select与el-tooltip踩坑

1、问题

可以详见这个issues。https://github.com/element-plus/element-plus/issues/9414icon-default.png?t=N7T8https://github.com/element-plus/element-plus/issues/9414

总的来说就是使用 el- select 与 el-tooltip 的地方会导致渲染出现问题,比如这里。

    <!-- 导航栏 -->
    <!-- <no-ssr> -->
    <nav class="navbar">
      <div class="navbar-box">
        <div style="font-size: 24px">云原生应用市场</div>
        <div>
          <ul>
            <li>
              <a :href="`/docs`" target="_blank"> 文档 </a>
            </li>
            <li>
              <el-popover :width="160" placement="bottom" trigger="hover">
                <template #default>
                  <div>
                    <img
                      class="wechart"
                      :src="
                        marketInfo &&
                        marketInfo.banners &&
                        marketInfo.banners.length > 0 &&
                        marketInfo.banners[0].imageURL
                      "
                      alt=""
                    />
                    <p
                      style="
                        font-size: 12px;
                        margin-bottom: 0px;
                        margin-top: 6px;
                        text-align: center;
                      "
                    >
                      扫一扫,邀你进群交流吧
                    </p>
                  </div>
                </template>
                <template #reference>加入群聊</template>
              </el-popover>
            </li>
            <li>
              <a :href="`/enterprise/login`"> 登录 </a>
            </li>
          </ul>
        </div>
      </div>
    </nav>
    <!-- </no-ssr> -->

运行效果:

 

可以看到,我这里点击跳转以后地址栏发生了变化,但是页面并没有跳过去,而且控制台也报错。Uncaught (in promise) TypeError: Cannot read properties of null (reading 'parentNode') 

 解决方法

使用 <no-ssr></no-ssr> 把对应的 el- select与el-tooltip 包裹住,让这一小段代码不使用ssr渲染,从上面的issues也可以看到这是element plus的一个bug,但是截止到目前仍未修复。

总结:坑还是挺多的,而且很多问题虽然解决了但不知道是为什么(有知道为什么的大佬如果您不嫌弃的话麻烦给我讲解一下),因为这个玩意已经加了两周多的班了,终于捋出来一些头绪了。终于也是快接近尾声了。seo优化这个词也终于从我的面试八股文中走了出来真真切切的体验了一把,虽然过程很艰难,但好在最难的时刻已经过去啦。加油加油各位!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/951705.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新版HBuilderX在uni_modules创建搜索search组件

1、创建自定义组件 my-search 新版HBuilder没有了 component 文件夹&#xff0c;但是有 uni_modules 文件夹&#xff0c;用来创建组件&#xff1a; 右键 uni_modules 文件夹&#xff0c;点击 新建uni_modules创建在弹出框&#xff0c;填写组件名字&#xff0c;例如&#xff1a…

分布式集群——搭建Hadoop环境以及相关的Hadoop介绍

系列文章目录 分布式集群——jdk配置与zookeeper环境搭建 分布式集群——搭建Hadoop环境以及相关的Hadoop介绍 文章目录 前言 一 hadoop的相关概念 1.1 Hadoop概念 补充&#xff1a;块的存储 1.2 HDFS是什么 1.3 三种节点的功能 I、NameNode节点 II、fsimage与edits…

Go的数据结构-hashmap

开放寻址法和拉链法 runtime.hamp bucket的数据结构 bucket的指针指向这里 map初始化&#xff1a;make 和字面量 make初始化 新建一个hamp结尾体&#xff0c;计算大B&#xff0c;创建一个桶数组 字面量初始化 map的并发解决 sync.map

25.CSS自定义形状按钮与悬停效果

效果 源码 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>CSS Custom Shape Button</title><link rel="stylesheet" href="style.css"> </head> <body&…

对战ChatGPT,创邻科技的Graph+AI会更胜一筹吗?

大模型&#xff08;大规模语言模型&#xff0c;即Large Language Model&#xff09;的应用已经成为千行百业发展的必然。特定领域或行业中经过训练和优化的企业级垂直大模型则成为大模型走下神坛、真正深入场景的关键之路。 但是&#xff0c;企业级垂直大模型在正式落地应用前…

C++调用Python Win10 Miniconda虚拟环境配置

目录 前言1. Win10 安装 Miniconda2. 创建虚拟环境3. 配置C调用python环境4. C调用Python带参函数5.遇到的问题6. 总结 前言 本文记录了Win10 系统下Qt 应用程序调用Python时配置Miniconda虚拟环境的过程及遇到的问题&#xff0c;通过配置Python虚拟环境&#xff0c;简化了Qt应…

基于NAudio实现简单的音乐播放器

《测试.net开源音频库NAudio》介绍了使用NAudio实现音乐播放和录音的基本用法&#xff0c;本文基于NAudio的音乐播放功能实现简单的mp3音乐播放器程序&#xff0c;主要实现以下功能&#xff1a;   1&#xff09;导入文件夹中的mp3音乐文件&#xff0c;直接导入多个mp3音乐文件…

Unity 状态机

Enemy状态以及切换图 程序架构 接口 public interface IState {void OnEnter(); //进入状态时void OnUpdate();//执行状态时void OnExit(); //退出状态时 }接口实现及状态切换类 public class IdleState : IState {private FSM manager;private Parameter parameter;public…

最新ChatGPT程序源码+AI系统+详细图文部署教程/支持GPT4.0/支持Midjourney绘画/Prompt知识库

一、AI系统 如何搭建部署人工智能源码、AI创作系统、ChatGPT系统呢&#xff1f;小编这里写一个详细图文教程吧&#xff01;SparkAi使用Nestjs和Vue3框架技术&#xff0c;持续集成AI能力到AIGC系统&#xff01; 1.1 程序核心功能 程序已支持ChatGPT3.5/GPT-4提问、AI绘画、Mi…

什么回合制手游好玩不花钱?

回合制手游主要要求玩家在特定回合内运用不同的技能和策略&#xff0c;以在战斗中取得胜利。即使你不花钱&#xff0c;你也可以度过一段愉快的时光&#xff0c;因此深受玩家的喜爱。在这篇文章中&#xff0c;我们将介绍什么回合制手游好玩不花钱&#xff1f;并盘点2023年最受欢…

Java泛型机制

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;每天一个知识点 ✨特色专栏&#xff1a…

el-table表尾添加合计行,自动合计,且特殊列自定义计算展示

效果如图 1.element-ui的table表格有合计功能&#xff0c;但是功能却不完善&#xff0c;会有不显示和计算出现错误的问题&#xff0c;项目中有遇到&#xff0c;所以记录下 show-summary&#xff1a;自动合计 getSummaries&#xff08;&#xff09;&#xff1a;对合计行进行特…

Unity 粒子特效遮罩(ParticleMask)

1.需求&#xff1a; 游戏中粒子特效能实现非常好的效果&#xff0c;但是由于粒子特效是独立的系统&#xff0c;Unity自带的Mask普通的遮罩&#xff0c;遮不住粒子特效。 2.实现原理&#xff1a; 通过shader把超出范围的粒子纹理(Texture)&#xff0c;改成透明颜色&#xff0…

CS144(2023 Spring)Lab 1: stitching substrings into a byte stream

文章目录 前言其他笔记相关链接 1. Getting started2. Putting substrings in sequence2.1 需求分析2.2 注意事项2.3 代码实现 3. 测试与优化 前言 这一个Lab主要是实现一个TCP receiver的字符串接收重组部分。 其他笔记 Lab 0: networking warmup Lab 1: stitching substri…

【Datawhale】AI夏令营第三期——基于论文摘要的文本分类笔记(上)

暑期参加了Datawhale的第三期AI夏令营&#xff0c;学习的是NLP方向&#xff0c;在此期间&#xff0c;我们通过比赛打榜的形式进行NLP的学习。今天&#xff0c;主要分享和记录一下这一期夏令营的学习历程和笔记。 文章目录 赛题背景赛题任务赛题数据集评价指标解题思路任务一&am…

C++之“00000001“和“\x00\x00\x00\x01“用法区别(一百八十六)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

NTP时钟同步服务器

目录 一、什么是NTP&#xff1f; 二、计算机时间分类 三、NTP如何工作&#xff1f; 四、NTP时钟同步方式&#xff08;linux&#xff09; 五、时间同步实现软件&#xff08;既是客户端软件也是服务端软件&#xff09; 六、chrony时钟同步软件介绍 七、/etc/chrony.conf配置文件介…

75 # koa 基本逻辑实现以及属性的扩展

准备工作 新建自己的 kaimo-koa 文件夹&#xff0c;结构如下&#xff1a; lib application.js&#xff1a;创建应用context.js&#xff1a;上下文request.js&#xff1a;koa 中自己实现的 request 的对象response.js&#xff1a;koa 中自己实现的 response 的对象 package.js…

HTTPS安全通信和SSL Pinning

随着互联网的迅速发展&#xff0c;网络通信安全问题日益凸显。在这一背景下&#xff0c;HTTPS作为一种加密通信协议得到了广泛应用&#xff0c;以保障用户的数据隐私和信息安全。本文将介绍HTTPS的基本原理、发展历程&#xff0c;以及与之相关的中间人攻击和防护方法。 1. HTT…

MySQL基础入门

推荐查看 数据库相关概念 MySQL百度百科 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS (Relational Databa…