Tom`s BlogTom`s Blog
Home
文章
分类
标签
最新
Home
文章
分类
标签
最新
Sticky Article with Higher Priority

Date: 1/1/2020Category: backendTag: tag E

Excerpt information which is added manually.

Sticky Article

Date: 1/1/2021Category: frontendTag: tag E

A sticky article demo.

闭包与this和函数上下文调用

Category: Tag:

闭包

概念:可以访问到其他函数内部变量的函数

作用:解决变量污染(一般用于回调函数)

备注:非必要不用闭包,如果子函数一直没有接收到参数可能导致内存一直无法释放(函数未执行完成,知道运行完成后才会执行垃圾回收)

function power(base, exponent) {
  if (exponent == 0) {
    return 1;
  } else {
    return base * power(base, exponent - 1);
  }
}

console.log(power(2, 3));
// → 8

Date: 7/6/2025Category: backendTag: node, backend

CORS跨域

// 设置后端响应头
// 设定运行访问的源(域,协议,端口)
response.setHeader('Access-Control-Allow-Origin', '*');
// 设定运行访问的方法
response.setHeader('Access-Control-Allow-Methods', '*');
// 设定运行访问的自定义请求头
response.setHeader('Access-Control-Allow-headers', '*');
// 是否允许携带身份凭证
response.setHeader('Access-Control-Allow-Credentials', '*');
// 指定预检请求的缓存时间
response.setHeader('Access-Control-Allow-Max-age', '*');
爱丽丝:疯狂回归 60 帧设置

Date: 7/6/2025Category: weekendTag: Game, Game option

简介

《爱丽丝:疯狂回归》(英语:Alice: Madness Returns,香港和台湾译作“爱丽丝惊魂记:疯狂再临”)是一款由上海麻辣马工作室开发并由艺电发行的恐怖题材的动作冒险游戏,本作是 2000 年 10 月 6 日推出的《爱丽丝梦游魔境》(American McGee's Alice)的续集。

回调函数

Date: 7/6/2025Category: backendTag: common sense

什么是回调函数

回调函数:将一个函数作为参数传递到另外一个函数中,并在另一个函数当中调用

js 体验AI代码助手 代码解读复制代码function fn1(f) { // 回调函数,接收的是函数
  console.log('fn1');
  f() // 调用接收进来的函数
}
function fn2() {
  console.log('fn2');
}
fn1(fn2)
JS执行环境+作用域(上下文)

Date: 7/6/2025Category: frontendTag: frontend, backend, common sense, javascript, nodejs

函数

执行环境

  • 执行环境(执行上下文)是JS中非常重要的一个概念。
  • 每个执行环境都有一个与之关联的虚拟对象(执行上下文对象)
  • 执行环境中定义的所有变量和函数都保存在这个执行上下文对象中,供解析器在处理数据时使用。

预处理

  • 将变量和函数作为执行上下文对象的属性放到这个对象上的这个过程,被称为预处理
  • 预处理发生在代码将要执行之前
  • 虽然JS是解释执行的语言,但是在解释执行之前,还是有个预处理的过程
  • 为代码的执行做准备,提前检查出代码中的错误
  • 算是做了一个通篇扫描的过程
  • 这也是之前讲过的变量的声明提升和函数提升的原因
cookie and storage

Date: 6/16/2025Category: frontendTag: node, backend

Cookie

说明:

cookie由键值对字符串组成, 在设置Cookie时,可以指定以下属性:

对document.cookie 重新赋值即可新增该Cookie, 而不是替换掉整个Cookies 。

注意:如果需要替换某个Cookie, 必须保证Domain与Path一致。其中 Cookie 内容只能包括 Ascii 码字符,所以需要经过一层编码。

Cookie的跨域传输

Date: 6/16/2025Category: backendTag: node, backend

问题描述

1.后端已设置允许跨域,使用Express传递携带session的cookie给前端,在响应体的set-cookie 里面有值,但前端没有存储cookie同时在Application中并没有存储cookie值。

2.原因是前端没有设置允许跨域传递cookie,给xhr的属性withCredentials赋值为true即可。

解决方法

1.后端允许跨域

app.use((req, res, next)=>{
    // 设置允许跨域的域名
    res.set('Access-Control-Allow-Origin', req.headers.origin);
	res.set('Access-Control-Allow-Methods', '*');
	res.set('Access-Control-Allow-headers', '*');
	res.set('Access-Control-Allow-Max-age', '*');
    // 允许跨域传递cookie
	res.set('Access-Control-Allow-Credentials', true);
    next();
})


Date: 6/16/2025Category: backendTag: node, backend

Express框架基础

// express 框架生成器
npx express-generator
// 安装express
npm install express
// 安装自动更新包
npm install nodemon
// 基本使用
const express = require('express')
const app = express()
// 静态文件中间件
const path = require('path')
app.use(express.static('public'))
app.use('/static', express.static(path.join(__dirname, 'public')))
// 全局中间件
const myLogger = function(req, res, next){
    console.log('log')
    next()
}
// 根据路由接收请求
app.get('/', (req, res)=>{
    res.send('hello world!')
})
// 局部中间件
app.post('/', function(req, res, next){
    console.log("执行了局部中间件")
    next()
},(req, res)=>{
    res.send('hello world!')
})
app.put('/user', (req, res)=>{
    res.send('hello world!')
})
// 无匹配请求地址处理
app.all('*', (req, res, next)=>{
    res.send("找不到改请求地址")
    next()
})
// 服务器请求的异常处理
app.use((err, req, res, next)=>{
    console.log(err.stack)
    res.status(500).send("服务器出错")
})


app.listen(port, ()=>{
    console.log(`server is runing, port:${port}`)
})



// express 的模板引擎
// 设置模板文件夹和模板引擎
app.set('views', __dirname+"/views")
app.set('view engine', 'ejs')
var indexRouter = require('./routes/index')
app.get('/user', indexRouter)
// 下列代码为routes/index.js路由文件中的代码
router.get('/', function(req, res){
    //调用模板解析引擎渲染页面,名为index的模板并传入一个对象为参数
    res.render('index', {title: 'Express'})
})
module.exports = router





NODE与邮箱邮件发送

Date: 6/16/2025Category: backendTag: node, backend

NODE与邮箱邮件发送

邮箱验证码思路

验证码发送阶段

客户端上传邮箱地址到服务端,服务端通过生成随机验证码,并将这个验证码发送到用户上传的这个邮箱中。此时服务端需要将这个邮箱和验证码保存到数据库的某张表中(后文中使用Code来称呼这个表),同时保证这条记录的唯一性。并在有效时间内将这条记录删除(此时间就是验证码的有效时间)

验证码验证阶段

客户端将收到的验证码和邮箱重新发送到服务端,服务端开始验证:

是否能够从Code中查询到这条验证码和邮箱与客户端发送一致的记录 是:验证通过,并删除这条记录 否:验证不通过 验证码发送阶段 ————————————————

NODE中使用UUID

Date: 6/16/2025Category: backendTag: node, backend
// 用于生成UUID
const crypto = require('crypto');
// 生成UUID
const uuid = crypto.randomUUID();
NODE原生HTTP

Date: 6/16/2025Category: backendTag: node, backend

创建基本的Node服务器并接收http请求(原生)

const port = 3000;
const hostName = '127.0.0.1';
const http = require('http')
const fs = require('fs')
const url = require('url');
const server = http.createServer((req, res)=>{
    // 接收POST请求
    let data = ""
    if (req.method === 'POST') {
        const { query, pathname } = url.parse(req.url, true);
        if (pathname == "/post/userInfo") {
            req.on('data', chunk => {
                // 拼接数据
                data += (chunk);
            })
            req.on('end', () => {
                data = JSON.parse(data)
                console.log(data)
            })
        }
    }
}.listen(port, hostName, () => {
    console.log(`服务器已启动:${hostName}:${port}`)
})
// 接收GET请求
server.on('request', (requset, response) => {
    const { query, pathname } = url.parse(requset.url, true);
    // 这里使用JSON.stringify(query)和JSON.parse(data)进行转换为对象 防止出现 [Object: null prototype] 的警告
    let data = JSON.stringify(query);
    data = JSON.parse(data);
    response.writeHead(200, { 'Content-type': 'text/plain' });
    response.end('服务器已接收GET请求')
})
SEESION与JWT

Date: 6/16/2025Category: backendTag: node, backend

Session

说明

session类似服务器端的cookie,保存于服务器端,类似于服务器缓存。用户登陆了总需要验证吧,那么就在session中验证即可,session和cookie是一一对应关系。

session的创建顺序

  1. 生成全局唯一标识符(sessionid);

  2. 开辟数据存储空间。一般会在内存中创建相应的数据结构,但这种情况下,系统一旦掉电,所有的会话数据就会丢失,如果是电子商务网站,这种事故会造成严重的后果。不过也可以写到文件里甚至存储在数据库中,这样虽然会增加I/O开销,但session可以实现某种程度的持久化,而且更有利于session的共享;

  3. 将session的全局唯一标示符发送给客户端。 问题的关键就在服务端如何发送这个session的唯一标识上。联系到HTTP协议,数据无非可以放到请求行、头域或Body里,基于此,一般来说会有两种常用的方式:cookie和URL重写。

  4. Cookie是如何被设置的呢?是被服务器返回的请求设置的。

  5. 服务器会返回一个set-cookie的消息,通知浏览器要设置cookie了,于是浏览器会根据set-cookie里的字段来设置信息了.

NODE与MYSQL

Date: 6/16/2025Category: backendTag: node, backend

mysql

const mysql = require('mysql')
const mysqlCnn = mysql.createConnection({
    user: "admin",
    password: "Mm2332868127.",
    host: "localhost",
    database: "bilibili"
})

mysqlCnn.connect(err=>{
    if(err){
        console.warn(`连接mysql数据库失败!错误原因为: ${err}`)
    }else{
        console.log("连接mysql服务器成功!")
    }
    
})

// // 增
// mysqlCnn.query("INSERT INTO user (user_id, account, password) VALUES (223456, 'Tom3323', '12345678')", (err, result)=>{
//     if(err){
//         console.log(`数据更新出错!错误信息为: ${err}`)
//     }
// })
// // 删
// mysqlCnn.query("DELETE FROM user WHERE user_id = 11111", err=>{
//     if(err){
//         console.log(`数据更新出错!错误信息为: ${err}`)
//     }
// })
// // 改
// mysqlCnn.query("UPDATE user SET account = 'jerry', password = '333333' WHERE user_id = 11111 ", (err, result)=>{
//     if(err){
//         console.log(`数据更新出错!错误信息为: ${err}`)
//     }
// })
// // 查
// mysqlCnn.query(SELECT * FROM user WHERE account='tomweichat@qq.com' and password='12345678' , (err, result)=>{
//     if(err){
//         console.log(`数据更新出错!错误信息为: ${err}`)
//     }
// })
// 断开连接
mysqlCnn.release()
module.exports = mysqlCnn
GIT的基本使用

Date: 6/16/2025Category: weekendTag: GIT

基本使用

// 这个命令,会在“~/.gitconfig”中以如下形式输出设置文件。
$ git config --global user.name "Firstname Lastname"
$ git config --global user.email "your_email@example.com"
[user]
  name = Firstname Lastname
  email = your_email@example.com

// 将 color.ui 设置为 auto 可以让命令的输出拥有更高的可读性。
git config --global color.ui auto
// “~/.gitconfig”中就会增加下面一行。
[color]
  ui = auto

//生成SSH后复制至GitHub同步
git-keygen -t rsa -C
// 1. git初始化 (必须初始化)
git init
// 2. 查看仓库状态
git status
// 3. 向暂存区添加文件
git add
// 4. 保存仓库的历史纪录 git commit -m "快速备注"。vim编辑器使用i进行输入,写详细备注时第一行是简要内容,第二行空行,第三行是详细内容。输入完成后按ESC输入:wq完成编辑
git commit
// 中止提交
如果在编辑器启动后想中止提交,提交信息留空并直接关闭编辑器,随后提交就会被中止。
// 修改上一条提交的信息
git commit --amend
// 5. 查看提交日志 git log -p可查看文件的改动
git log
// 6. 查看当前暂存区与工作树的差别,git diff HEAD是最新差别
git diff

// 显示分支一览表  git branch -a可以查看当前仓库和远程仓库的分支信息
git branch 
// 切换分支
git checkout -b 分支名
// 合并分支
git merge --no-ff 分支名
// 以图标形式查看分支
git log --graph
// 回溯历史版本
git reset --head 历史版本的哈希值
// 查看当前仓库执行过的操作的日志
git reflog

// 添加远程仓库
git remote add origin git@github.com:用户名称/仓库名.git
// 推送至远程仓库 -u参数是设置为本地仓库的上游(upstream)
git push -u origin master
// 获取远程仓库
git clone git@github.com:用户名称/仓库名.git

// 本地commit回退.回退到某次commit
git reset --hard commitID
// 本地commit回退后,提交让远程仓库同步回退
git push -f origin main
CSS基础

Date: 6/16/2025Category: frontendTag: css, html

SEO

常用方法

  1. 标签语义化
  2. 竞价排名(花钱)
  3. 网页制作成 HTML 后缀

网页头部三大标签

  1. title 网页标题
  2. description 网页描述
  3. 网页关键词

Favicon 图标

<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" >
Cookie与Storage

Date: 6/16/2025Category: frontendTag: html, javascript, frontend

Cookie

说明:

cookie由键值对字符串组成, 在设置Cookie时,可以指定以下属性:

对document.cookie 重新赋值即可新增该Cookie, 而不是替换掉整个Cookies 。

注意:如果需要替换某个Cookie, 必须保证Domain与Path一致。其中 Cookie 内容只能包括 Ascii 码字符,所以需要经过一层编码。


Date: 6/16/2025Category: frontendTag: node, backend

Promise

Promise的介绍

Promise是异步编程的一种解决方案,它的构造函数是同步执行的,then 方法是异步执行的,所以Promise创建后里面的函数会立即执行,构造函数中的resolve和reject只有第一次执行有效,,也就是说Promise状态一旦改变就不能再变

原型与面向对象

Date: 6/16/2025Category: frontendTag: http, frontend, javascript

一切皆对象

原型和原型链都是来源于对象而服务于对象的概念,所以我们要先明确一点:

JavaScript中一切引用类型都是对象,对象就是属性的集合。

Array类型、Function类型、Object类型、Date类型、RegExp类型等都是引用类型。

也就是说 数组是对象、函数是对象、正则是对象、对象还是对象。

原型与原型链是什么

原生与Fetch的HTTP请求

Date: 6/16/2025Category: frontendTag: http, frontend, javascript

原生请求

// 发起GET请求
const xhr = new XMLHttpRequest;
xhr.open('GET', 'http://127.0.0.1:3000?name=tom&password=123456')
xhr.onload = () => {
    console.log(xhr.status)
    if (xhr.status === 200) {
        console.log(xhr.responseText)
    } else {
        console.log(`Error:${xhr.status}`)
    }
}
xhr.send();
// 发起POST请求
const xhr = new XMLHttpRequest;
xhr.open('POST', 'http://127.0.0.1:3000/post/userInfo');
xhr.setRequestHeader('Content-type', 'application/x-www-formurlencoded');
xhr.onload = () => {
    if (xhr.status = 200) {
        console.log(xhr.responseText);
    } else {
        console.error(`Error:${xhr.statis}`);
    }
};
xhr.send(JSON.stringify({
    name: "12312321",
    email: "131123@qq.com"
}))