title

quick notes

随笔小记

  • react 项目中父组件和子组件被withRouter等高阶组件修饰后,父组件就不能再使用ref来获取子组件的指针了,因为函数组件中无this

    • 使用wrappedComponentRef来代替ref来包裹子组件

      <BasicInfo wrappedComponentRef={(fn) => (this.basicInfoRef = fn)} />
  • Promise.all 接收函数执行的数组,返回一个数组

    const requestArray = [ this.basicInfoRef.requestInfo(id), this.probeRecycleRef.requestInfo(id), this.sitesInfoRef.requestInfo(id), ] Promise.all(requestArray) .then((res) => { console.log('==>', res) }) .catch((err) => { console.log('err', err) })
  • 跨域问题

    • CORS 只限制浏览器环境( chrome/edge/firefox/...)
    • 对方允许跨域( response header)
    • 当前域允许跨域( content-security-policy)
    • 动态 script 标签引用跨域 js ( src=xxx.php?.js )不算 [请求跨域] ,算资源跨域,一般不需要对方服务器许可(当然对方可以根据 referer 来进行限制),同时受 content-security-policy 限制
    • 编程发起的请求(js/python/curl/php/java/go...)不受任何限制( cors 、content-security-policy),哪怕对方服务器的安全防护你也可以进行绕过
  • 浏览器缓存

    • 缓存的位置分为私有缓存和公共缓存

      • 私有缓存一般在客户端的浏览器
      • 公共缓存一般在内容分发网络CDN(网络层面)
    • 缓存的类型:

      • 强缓存: 客户端不与服务端进行通信协商的缓存

        • eg: cache-control: public,max-age: 3000

          • 内容可被公共网络缓存,缓存时效3s
          • 在3s内客户端一直使用缓存内容,大于3s重新拉取新内容
      • 协商缓存:客户端需要与服务端进行通信协商的缓存

        • eg:

          • 响应头: cache-control: no-cache

          • 请求头:

            • if-Modified-Since: LastModified
            • if-None-Match: Etag
            • 上述二者必须存在一个,否则no-cache将失效,代表无缓存;二者可同时存在更精确
          • 命中协商缓存后,服务端会返回304,告知浏览器内容无需更新,继续读取缓存内容,前端无需操作

      • 弱缓存: 缓存内容只允许在私有缓存存储

        • eg:

          • 响应头: cache-control: private,max-age: 3000
        • 不允许在公共缓存存储,在3s内是否更新由私有存储(比如浏览器)自行支配,3s后重新拉取数据

  • 304: 临时性重定向,响应头会在headers中location中携带新地址,浏览器自动跳转,前端无需处理

  • 针对接口返回的Blob和ArrayBuffer等二进制时

    • 前端可以通过在请求头中指出responseType: ‘blob’, 来让axios和fetch自动将response转为Blob数据

    • 通过new Response() 改写response,通过text() 获取Promise内容

      (async() =>{ const res = new Response(response).text() //获取Promise内容 const resToBlob = res.blob() //转为Blob数据 // 转为Blob的数据还可以通过Blob对象 // const resToBlob = new Blob([response]) const url = URL.createObjectURL(resToBlob) //生成Blob数据对应的url })()
  • class 继承

    • 子类必须调用super()

      • 执行父类的构造函数,防止未初始化出现bug
      • 不写constructor的话,会隐式默认调用
    • super 作为关键字时

      • 在原型函数指向父类的原型对象

      • 在静态函数中使用指向父类的构造对象

      • *注意父类的箭头函数

        • 箭头函数从指向原型对象改变为指向构造函数
      • 一般只作为子类函数在不改变父类函数的基础上拓展父类函数

  • 文件夹中所有图片更改为.webp格式

    • 安装 cwebp 工具。cwebp 是一个命令行工具

    • 在终端中进入存储图片的文件夹。

    • 使用以下命令将所有 PNG 图片转换为 WebP 格式

      for file in *.png; do cwebp -q 75 "$file" -o "${file%.png}.webp"; done
  • nest 的核心实现原理:通过装饰器给 class 或者对象添加 metadata,并且开启 ts 的 emitDecoratorMetadata 来自动添加类型相关的 metadata,然后运行的时候通过这些元数据来实现依赖的扫描,对象的创建等等功能。

  • MacOS 10.15.7 版本安装Docker Desktop

  • Docker

    • 打镜像

      • docker build -t name:tag .

        • -t 代表tag ⇒name:tag
        • . ⇒ 代表当前目录去找Dockerfile
        • -f ⇒指定Dockerfile
    • 生成容器

      • docker run —name name -p 3000:3000 -d image_name

        • -p 自定义端口对应image的端口
        • -d 代表后台运行,不打印运行log
        • -v 代表宿主机和image的挂载卷 eg: /aaa:/bbb/ccc
        • -e 设置环境变量 eg: -e ENV=test
    • 查看容器

      • docker exec -it container_id /bin/sh
    • pm2

      • 在容器内使用pm2

        • CMD [”pm2-runtime”, “/app/main.js”]
    • mysql

      • 拉取镜像

        • docker pull mysql
      • 创建容器

        • docker run --name mysql -d -v /Users/zs/Desktop/volumn_mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=shuai -p 3306:3306 mysql

          • mysql 保存数据的路径: /var/lib/mysql
          • -e 设置环境变量,此处设置密码变量
          • 3306端口就是client连接mysql的端口