最近接到消息,项目做的上传图片功能被通知需要做下安全审核。在解该决问题后,这里Mark下。

当前我用的是腾讯云的COS- CDN,这里以此产品为例介绍下。

当前COS使用

图片当前上传是走的COS,存储后返回路径,COS我通过绑定域名走CDN供用户使用。

审查配置

  1. COS支持配置图片自动审查,由于我的COS还配置有其它的资源,因此这里我开启了图片自动审查的COS路径限制,比如/user-images的才开启审查。
  2. 由于我的图片上传功能之前就已上线,因此面临存量和新增的2部分图片如何处理
    1. 存量图片通过配置任务让COS再做下审查
    2. 新增图片我是通过COS- SDK,在上传后会自动触发审查
  3. 配置审查不合规后动作处理,这里考虑到用户图片可能是存在误判或者说当前标准过严,因此配置为审查违规后自动移动到指定目录,这样还有机会恢复。
  4. 由于配置审查是后置的,因此COS上传环境无感知会违规否,因此如果项目中想提示用户违规问题,还是需要自行调用审查接口或者配置审查回调接口。否则就会是上传成功不会提示违规,但实际访问404,原因是图片后置审查违规后被处理。
阅读全文 »

ssh2-sftp-client提供了put方法,可以传入可读流将数据持续写入远程文件。最近遇到问题是当写入流刚开始程序终端的话,会发现文件内容被清空。这里分析下原因

put方法中localSrc可以是可读流。remotePath即远程服务器中文件路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
async put(localSrc, remotePath, options) {
try {
if (typeof localSrc === 'string') {
const localCheck = haveLocalAccess(localSrc);
if (!localCheck.status) {
throw this.fmtError(
`Bad path: ${localSrc} ${localCheck.details}`,
'put',
localCheck.code,
);
}
}
return await this._put(localSrc, remotePath, options);
} catch (e) {
throw e.custom ? e : this.fmtError(`Re-thrown: ${e.message}`, 'put', e.code);
}
}

根据远程文件路径,sftp创建了可写流,writeStreamOptions设置了可写流的一些配置。可读流不断读取写入SFTP的可写流中。

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
_put(lPath, rPath, opts, addListeners = true) {
let listeners, wtr, rdr;
return new Promise((resolve, reject) => {
if (addListeners) {
listeners = addTempListeners(this, '_put', reject);
}
opts = {
readStreamOptions: { ...opts?.readStreamOptions, autoClose: true },
writeStreamOptions: { ...opts?.writeStreamOptions, autoClose: true },
pipeOptions: { ...opts?.pipeOptions, end: true },
};
if (haveConnection(this, '_put', reject)) {
wtr = this.sftp.createWriteStream(rPath, opts.writeStreamOptions);
...
if (lPath instanceof Buffer) {
this.debugMsg('put source is a buffer');
wtr.end(lPath);
} else {
rdr =
typeof lPath === 'string'
? fs.createReadStream(lPath, opts.readStreamOptions)
: lPath;
...
rdr.pipe(wtr, opts.pipeOptions);
}
}
}).finally(() => {
if (addListeners) {
removeTempListeners(this, listeners, '_put');
}
});
}
阅读全文 »

今天看到公司内部平台推送了一道关于parseInt的问题,发现结果出乎一聊,根本原因是对于parseInt执行理解不清晰,这里Mark下。

问题

1
2
3
4
5
6
7
8
9
10
11
parseInt('0xf',16)
// 15

parseInt('0xf')
// 15

parseInt(0xf,16)
// 21

parseInt(15,16)
// 21

解释

  1. parseInt第一个参数,会从首个非空格字符开始,对于非字符串会做ToString转换,因此parseInt(15,16)本质就是parseInt(‘15’,16)。
  2. parseInt(‘0xf’,16),JS识别字符串是16进制数字,radix也是16进制,因此直接解析为15。parseInt(‘0xf’)虽然没有传radix,但是根据字符串0x前缀还是识别为16进制因此还是15。
阅读全文 »

腾讯云函数用了几次了,确实很方便。腾讯云函数就是serverless产品。这里从云函数的使用上理解下serverless。

需求1

在开发微信小程序时需要个中间服务端,其业务非常简单,更多是调用大后端,云函数里只是简单的分发请求和DB查询操作。如果自己部署有成本。考虑后决定使用云函数。

使用云函数后,就不需要关心服务器运维了。

需求2

阅读全文 »

手里目前有三台MBP,因此决定把一台19款做下回收,之前没尝试过闲鱼回收,这次试试。

最新更新

由于闲鱼砍价太狠,直接提出退回,闲鱼电话联系说加价400-500CNY。考虑到水份太高,直接拒绝回收了。

最终走JD-爱回收处理,采用了线上提单,线下交易的方式。

so,下述闲鱼回收仅供参考了,毕竟目前觉得太败感了。

阅读全文 »

看推上有人提到IPv6直播源观看稳定性高,我之前也没搞过v6,因此尝试把家里网络支持下。

这里记录下操作流程。

硬件情况

先说下牵扯的几个硬件

  • 联通光猫
  • 中兴路由器
  • 终端设备如Mac/Apple TV/iPhone等

这里开始设置。

阅读全文 »

ChatGPT火了一年了,技术上的话也带动了SSE的使用。这里也总结下我对它的认识。

SSE的优势

  1. 使用标准的HTTP协议,并非WebSocket。相对比WebSocket全双工资源开销相对较小。
  2. SSE传输的文本数据,使用开销简单。

服务端实现

阅读全文 »

xterm.js中监听按键执行特殊处理需要用到attachCustomKeyEventHandler,这里说明下。

源码解读

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
/**
* Attaches a custom key event handler which is run before keys are
* processed, giving consumers of xterm.js ultimate control as to what keys
* should be processed by the terminal and what keys should not.
* @param customKeyEventHandler The custom KeyboardEvent handler to attach.
* This is a function that takes a KeyboardEvent, allowing consumers to stop
* propagation and/or prevent the default action. The function returns
* whether the event should be processed by xterm.js.
*
* @example A custom keymap that overrides the backspace key
* ```ts
* const keymap = [
* { "key": "Backspace", "shiftKey": false, "mapCode": 8 },
* { "key": "Backspace", "shiftKey": true, "mapCode": 127 }
* ];
* term.attachCustomKeyEventHandler(ev => {
* if (ev.type === 'keydown') {
* for (let i in keymap) {
* if (keymap[i].key == ev.key && keymap[i].shiftKey == ev.shiftKey) {
* socket.send(String.fromCharCode(keymap[i].mapCode));
* return false;
* }
* }
* }
* });
* ```
*/
attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void;

源码位置

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
protected _keyDown(event: KeyboardEvent): boolean | undefined {
this._keyDownHandled = false;
this._keyDownSeen = true;

if (this._customKeyEventHandler && this._customKeyEventHandler(event) === false) {
return false;
}
...
}
protected _keyUp(ev: KeyboardEvent): void {
this._keyDownSeen = false;

if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {
return;
}
...
}
protected _keyPress(ev: KeyboardEvent): boolean {
let key;

this._keyPressHandled = false;

if (this._keyDownHandled) {
return false;
}

if (this._customKeyEventHandler && this._customKeyEventHandler(ev) === false) {
return false;
}
...
}

阅读全文 »

TinyMCE是个老牌的编辑器,查询发现TinyMCE使用的GNU-GPL开源协议,那我是否可商用,是否可以二次开发呢?带着这个疑问,了解下GPL。

解释

如下转自知乎的一个回答

GPL协议的目的就是强制代码开源和免费使用。

其最大的特点就是“开源的传染性”。也就是说,假设某公司使用了具有GPL协议的代码库,那么他理论上也必须把自己的代码库开源。

阅读全文 »

nodejs支持esmodule导入,通过import可以加载esmodule,但也有些条件,如果不满足仍然会报错。

注意:nodejs下import与浏览器侧有区别。

import本地JS模块

  1. js文件所在文件夹目录下package.json中声明type:module
  2. 文件后缀为mjs
阅读全文 »
0%