Skip to content
On This Page

202309

INFO

即将步入秋天,我还是这么菜吗?

20230906 是的

0901/0902

  • 815,距离婚期还有整整一个月

  • 多灾多难的一周,终于阔以休息下

  • gzip 的原理是什么,如何配置? gzip 的核心是 Deflate(缩小),而它使用了 LZ77 算法Huffman 编码来压缩文件,重复度越高的文件可压缩的空间就越大 因此 gzip 用于 HTTP 文件传输中,比如 JS、CSS 等,「但一般不会压缩图片」。在 HTTP Response 报文中,用 Content-Encoding 指明使用 gzip 压缩,而以下响应头在大部分生产环境的响应报文中都可以看到!

    txt
    Accept-Encoding: gzip, deflate, br
    Content-Encoding: gzip
    

    gzip 一般在反向代理那一层,如 nginx 进行处理,直接使用 C 语言编写,具有更好的性能。

在 nginx 开启 gzip: 配置可参考 gzip module[4]

js
gzip on;

0904

Server Component 它的渲染是在服务端完成之后通过网络请求交给客户端 React 做整合,如果运行时是 Node.js,在 Server Component 中就可以使用 Node.js 中的所有模块资源,访问数据库这些自然就可以了

0905

  • 818
  • 如何从技术岗转向产品岗?
  • 存量贷款利率 3000+2800 降 5800 就行

0906

  • 819,十一回来之后就是 849,元旦就是 900 天左右,天数在慢慢增长,不知道内功修炼的如何了?
  • Node.js 发布 v20.6.0 版本,从该版本开始增加了内置 .env 功能,运行时可以指定 .env 文件的路径,可以取代以往使用 dotenv 模块做的一些事情。
js
// .env
NODE_ENV = development

// app.js
console.log(process.env.NODE_ENV)

// 控制台执行
node --env-file=.env app.js

//控制台输出
development

需要注意。v20.6.0 现在还不是稳定版本,不建议用于生产环境,要成为 LTS 版本,到下半年 10 月份了。

To match a regex path you can wrap the regex in parenthesis after a parameter, for example /blog/:slug(\\d{1,}) will match /blog/123 but not /blog/abc:

js
module.exports = {
  async rewrites() {
    return [
      {
        source: "/old-blog/:post(\\d{1,})",
        destination: "/blog/:post", // Matched parameters can be used in the destination
      },
    ];
  },
};

0907

  • 如何解决跨域问题? 「协议」,「域名」,「端口」,三者有一不一样,就是跨域,案例一:www.baidu.comzhidao.baidu.com 是跨域。 目前有两种最常见的解决方案: 1.cors,需要在服务端设置几个响应头, 比如 Access-control-Allow-origin:/*/

    2.反向代理,在 nginx/traefik/haproxy 等反向代理服务器中设置为同一域名

js
server {
 listen 80;
 server_name bythewayer.com;

 location / {
   # 避免非root路径404
   try_files $uri $uri/ /index.html;
 }

 # 解决跨域
 location /api {
   # 或者是 http://localhost:8080
   proxy_pass http://api.bythewayer.com;
 }
}

3.JSONP

JSONP,全称 JSON with Padding,为了解决跨域的问题而出现。虽然它只能处理 GET 跨域,虽然现在基本上都使用 CORS 跨域,但仍然要知道它,毕竟面试会问。

JSONP 基于两个原理:

1.动态创建 script,使用 script.src 加载请求跨过跨域 2.script.src 加载的脚本内容为 JSONP: 即 PADDING(JSON) 格式

js
$ curl https://shanyue.tech/api/user?id=100&callback=padding

padding({
  "id": 100,
  "wechat": "xxxxx",
})

那请求数据后,如何处理数据呢?此时的 padding 就是处理数据的函数。我们只需要在前端实现定义好 padding 函数即可

js
window.padding = handleData;

基于以上原理,创建 jsonp

js
function jsonp_simple({ url, onData, params }) {
  const script = document.createElement("script");
  // 一、默认 callback 函数为 padding
  script.src = `${url}?${JSON.stringify({ callback: "padding", ...params })}`;
  // 二、使用 onData 作为 window.padding 函数,接收数据
  window["padding"] = onData;
  // 三、动态加载脚本
  document.body.appendChild(script);
}

// 发送 JSONP 请求
jsonp_simple({
  url: "http://localhost:10010",
  params: { id: 10000 },
  onData(data) {
    console.log("Data:", data);
  },
});

此时会有一个问题: window.padding 函数会污染全局变量,如果有多个 JSONP 请求发送如何处理?

js
function jsonp({ url, onData, params }) {
  const script = document.createElement("script");
  // 一、为了避免全局污染,使用一个随机函数名
  const cbFnName = `JSONP_PADDING_${Math.random().toString().slice(2)}`;
  // 二、默认 callback 函数为 cbFnName
  script.src = `${url}?${JSON.stringify({ callback: cbFnName, ...params })}`;
  // 三、使用 onData 作为 cbFnName 回调函数,接收数据
  window[cbFnName] = function (res) {
    onData(res);
    delete window[cbFnName];
    document.body.removeChild(srcipt);
  };
  document.body.appendChild(script);
}

// 发送 JSONP 请求
jsonp({
  url: "http://localhost:10010",
  params: { id: 10000 },
  onData(data) {
    console.log("Data:", data);
  },
});

0911

  • 824 时间过的飞快,可惜身体已经大不如前

  • 还有 20 多天即将步入新的时期

  • 技术还在原地踏步,心有力而余不足,能不能出去验证下

    想要维持学习状态,需要超强的牵引力和恒心,自己在这方面做的远远不够

  • 手写 axios 中的拦截器

js
class InterceptorManager {
  constructor() {
    this.handlers = [];
  }
  use({ fulfilled, rejected }) {
    this.handlers.push({
      fulfilled,
      rejected,
    });
  }
  eject(id) {
    if (id) {
      this.handlers[id] = null;
    }
  }
  forEach(fn) {
    this.handlers.foreach((item) => {
      item && fn(item);
    });
  }
}

0912

txt
- 用 CA 机构里的公钥(CA 机构的公钥是不需要传输的,操作系统提供的根证书里会存在)去解密数字证书中的**数字签名**(RSA/PSK),最终客户端 得到数字摘要 **hash value1**
- 客户端用证书里指定的 hash 摘要算法对明文数据(包含**服务器公钥**和**企业其他信息**)做加密,生成一份摘要 **hashCode2**。
- 然后两种比对 如果明文数据未被篡改,hashCode2 应该等于 hashCode1。
- 现在证书是可信的,就可拿到服务器的公钥。(为了得到最初服务器的公钥 真心不容易!!!)
  • 手写 requestIdleCallback?

这个 api 做啥用的来着

js
function requestIdleCallback(cb) {
  var now = Date.now();
  return setTimeout(() => {
    cb({
      didTimeout: false,
      timeRemaining: function () {
        return Math.max(0, 50 - (Date.now() - now));
      },
    });
  }, 0);
}
  • 禁止别人调试代码
js
(() => {
  function ban() {
    setInterval(() => {
      Function("debugger")();
    }, 50);
  }
  try {
    ban();
  } catch (err) {}
})();

0913

  • Nginx 中在 1.3.3 后已默认开启了协商缓存,手动配置如下:
js
server {
  location /public {
    add_header Cache-Control no-cache;
    etag on;
    if_modified_since exact;
  }
}
// 以下是在sever中添加cors
server {
  add_header 'Access-Control-Allow-Origin' '*';
  add_header 'Access-Control-Allow-Credentials' 'true';
  add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
}
  • 有 CSS 和 JS 两种方法,以下任选其一或结合使用实现页面文本不可复制
css
user-select: none;

或使用 JS 如下,监听 selectstart 事件,禁止选中。

当用户选中一片区域时,将触发 selectstart 事件,Selection API 将会选中一片区域。禁止选中区域即可实现页面文本不可复制。

js
document.body.onselectstart = (e) => {
  e.preventDefault();
};

document.body.oncopy = (e) => {
  e.preventDefault();
};

0914

  • 8xx 大环境不好,出去并不一定比现在好,有着难过的时间还不如好好学习,沉淀下自我
  • ts 联合转索引类型
ts
type UU = {
  age: number;
  name: string;
};

type IndexToUnion2<T> = {
  [P in keyof T]: {
    [K in P]: T[K];
  };
}[keyof T];
type UU2 = IndexToUnion2<UU>;

type UU3 =
  | {
      age: number;
    }
  | {
      name: string;
    };

type UnionToIndex<T> = (T extends T ? (x: T) => unknown : never) extends (
  x: infer R
) => unknown
  ? R
  : never;

type UU4 = UnionToIndex<UU3>;
// type UU4 = {
//     age: number;
// } & {
//     name: string;
// }

0915/0916

  • 9 月底之前要忙完手上的事,最近十天要忙死了
  • 周末还是不能太舒服,过的艰苦一点

0918

  • 8xx 天,未来压力可想而知
  • 有得有失,啥也不说了,好好赚钱,最近需要保养身体

0919

  • 832 天,目前因为结婚压力好大,自己只能劝自己不要想太多的事,把手头上的事做好就行,一步一步来

0925

  • 存量房贷利率从 5.1 降到 4.3,每个月少还 300,聊胜于无
  • 目前来看,我的压力在同龄中是比较大的,随时面临失业的风险,没有存款,近两年需要尽快攒够提前还房贷的钱

0926

在 Web 开发中,Cookie 可以设置多种属性来增强其安全性和功能。其中一个重要的属性是 "HttpOnly",它是一种安全标志,用于限制 Cookie 的访问权限。在设置了 HttpOnly 属性的情况下,浏览器将禁止通过 JavaScript 访问和修改 Cookie,从而有效地防止一些常见的攻击,例如跨站脚本攻击(XSS) 防止跨站脚本攻击(XSS): 跨站脚本攻击(XSS)是一种常见的 Web 攻击,攻击者通过注入恶意脚本来窃取用户的信息或执行未经授权的操作。其中一种常见的 XSS 攻击是通过 JavaScript 访问和修改 Cookie,以获取用户的敏感信息。通过将 Cookie 标记为 HttpOnly,可以防止这种类型的攻击。

  • web 项目如何使用思源宋体?

    1.下载思源宋体

    下载有点慢 需要点耐心

    2.设置 CSS 加载调用字体。为此,可以将如下的 CSS 代码存为一个 .css 文件,例如 fontssc.css

css
@font-face {
  font-family: "SiYuanSongBig";
  src: local("Source Han Serif CN"), local("Source Han Serif SC"),
    /*如果可能,调用本地字体*/
      url("fonts/Noto_Serif_SC/NotoSerifSC-Regular.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "SiYuanSongBig";
  src: local("Source Han Serif CN"), local("Source Han Serif SC"),
    /*如果可能,调用本地字体*/ url("fonts/Noto_Serif_SC/NotoSerifSC-Bold.otf")
      format("opentype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

body {
  font-family: "SiYuanSong", serif;
}

3.然后在文件中引入 css 使用定义号的 font-family 即可

js
import './fontssc.css'

//css
head {
  font-family: 'SiYuanSongBig', '宋体', 'Microsoft YaHei', sans-serif;
}