上传中文文件名文件- Linux 存储并本地 shell 等处理文件-回显文件名列表-按原文件名下载文件 的需求中,最优雅的编解码方式是什么?

2023-09-15 09:38:42 +08:00
 matepi
需求:

Steps
1) 用户通过浏览器上传文件至 linux 服务器,需支持原文件名带中文文件名,列表回显至用户
2) 文件在 linux 服务器上存储后,自动触发,通过 shell 脚本作为入口,进行文件的处理
3) 用户可以再浏览器上,看到已处理完成的原文件名+".result.txt"的文件,进一步下载回用户本地

问题:

直接上传文件名至服务器端,可能因 linux 服务器本地编码不同等原因直接就中文->??了。在需支持各种服务器编码情况下,进行中文文件名的编码是必须的。

但,哪种编码为最优? BASE64 ? HTML entity ?或其他?

BASE64 应该可以在 http 下载 http head 中,被浏览器下载文件过程中直接解码;
而 HTML entity 可以在浏览器页面回显中,被浏览器页面渲染直接解码;
同时这两种编码是否在 linux shell 调用过程中有需要转义,又多一步转义编码?

但同时隐忧,解码尽量利用浏览器行为,是否会有浏览器不兼容性的隐忧,或许不如就老老实实手动编码?


目的:

寻求一个最优雅文件名编码形式,适应上传后、服务器端存储、服务器端 linux shell 处理、浏览器回显、浏览器下载等多种场景下,编解码最少、最优雅、同时一定程度上考虑浏览器兼容性的中文文件名编码转化方式。
1265 次点击
所在节点    程序员
24 条回复
jifengg
2023-09-15 10:00:04 +08:00
“支持各种服务器编码”这个是真实情况还是臆想出来的?
服务器统一使用 UTF8 编码不行吗?

服务器端统一了,那全流程都是 utf8 编码,不会有问题的。(不要用 UTF8 BOM 头!!!)
mengzhuo
2023-09-15 10:23:55 +08:00
"通过 shell 脚本作为入口"

贵司是架构和安全都是吃干饭的么?要提供 webshell 给用户?随便一个提权命令都可以搞废你们这服务器。
matepi
2023-09-15 10:26:07 +08:00
@jifengg 做的是框架性通用性功能。如果要求服务器统一编码会限制通用性功能的使用范围。设计思路上是能减少一个用户要求,就减少一个用户环境要求。

而且,全流程 utf-8 会要求,不单单是服务器了。要求前端页面等也得 utf-8 、才能客户端浏览器以 utf-8 处理,这种传染形式,就更不利于框架性功能的推广了。
matepi
2023-09-15 10:28:00 +08:00
@mengzhuo 可能是我表达不清? txt 文件上传后,服务器端自动触发开发编写的 shell ,去进行对 txt 文件的数据处理。不是 webshell ,我不觉得这个有什么安全问题。
NessajCN
2023-09-15 10:34:51 +08:00
@matepi
第一,现在全程 utf-8 完全没问题
第二,你实在要其他编码,那就让前端把编码方式一起发回来就是了
NessajCN
2023-09-15 10:38:46 +08:00
@matepi 迷惑行为,既然是服务端行为,那你服务端用的语言没有 fs 写文件模块吗,为啥要调用 shell ?
matepi
2023-09-15 10:44:58 +08:00
@NessajCN 大概确实是我需求部分表达有问题了。服务器端调用 sed 、sqploader 、或其他自有工具等形式,对数据的文本清洗处理等后再加载。其中用 shell 作者为先后处理/加载的过程的总入口,我理解是最通用的一种文件上传处理框架中,需支持的入口模式了。我不能理解,fs 能够作为数据文件清洗/处理/加载的总入口吗?
NessajCN
2023-09-15 10:49:20 +08:00
@matepi
「 fs 能够作为数据文件清洗/处理/加载」
不然咧?
matepi
2023-09-15 10:53:13 +08:00
@NessajCN 求教了,如果我要用 fs 做一个:

1 、显示类似 sed 去掉数据文件行末和文末空格空行;

2 、在完成步骤 1 后,实现类似 sqlloader 工具,将处理后文件导入指定数据库。

这个应该如何做到呢?
NessajCN
2023-09-15 11:05:12 +08:00
const data = await fs.readFile("test.txt", "utf8")
const data_trim() = data.trim()

// 写文件
await fs.writeFile("test_trim.txt")

// 数据库
matepi
2023-09-15 11:12:57 +08:00
@NessajCN 还有略的部分,看来这个要处理的内容还是会比较多的。利用 linux 命令和现有 sqlloader 工具就能实现的,差不多几行脚本和工具调用命令,就能实现的话;个人还是感觉不大会有二次开发人员,去首选自己开发这些代码了。何况相比 shell ,还有多个 nodejs 环境基础依赖。nodejs 较 shell 来说,不是通用入口的优选。
NessajCN
2023-09-15 11:34:05 +08:00
@matepi
...因为你没说用啥语言所以我就拿 node 举个例子
你后端接口总是有个语言环境的啊,用那个的 fs/os/或什么模块不就没其他依赖了
matepi
2023-09-15 11:40:06 +08:00
@NessajCN 后端要交出这块数据处理调用给到二次开发手里的,既然是二次开发,就要选择最没有依赖、人人都能用起来的语言环境=>我选择 shell 作为首先要支持的语言环境、或者由二次开发选择通过 shell 再调用他们自己研发的语言代码的入口。
jptx
2023-09-15 11:54:59 +08:00
设计一张任务表或者类似的东西,用户上传时,相当于提交了一个任务。任务中可以有很多属性,比如原始文件名、任务类型、用户 ID 、任务创建时间、任务开始时间、任务结束时间、任务状态、任务简要日志等。
用户上传文件之后,自动在任务表中提交任务,记录下文件的原始名称。磁盘上实际存储文件时使用任务 ID 去作为文件名,这样你调用脚本时不需要关心原始文件名了,全程只需要关心任务 ID 。脚本执行完成之后根据任务 ID 去更新任务状态。结果文件保存时也是只关心任务 ID 。
用户下载结果文件时,在下载接口中根据任务中的原始文件名实时生成结果文件名。这样结果文件也不需要关心原始文件名了。
根据这个任务表,后面还可以增加更多的业务,比如批量导入、对接其他系统自动导入、重试导入、导入历史等等。
ysc3839
2023-09-15 11:56:51 +08:00
base64 ,因为 shell 下直接用 base64 -d 就能解码。html 那些连解码工具都没。
fo0o7hU2tr6v6TCe
2023-09-15 12:24:03 +08:00
好奇用 shell 怎么将数据加载到数据库的.. 还有文本处理 awk sed grep 这三件套处理简单的文本和数据清洗,一旦复杂起来,不专业点的老运维 review 都得半天.. 个人感觉..
matepi
2023-09-15 12:29:26 +08:00
@jptx 恩,这就是比老老实实手动编码的思路,更老老实实的思路了。确实有道理,展示层进出的时候就弄掉,中间一路干净也是是正道。
matepi
2023-09-15 12:37:39 +08:00
@hzjseasea 因为稍微正经点的数据库,都会有在 shell 下能够直接用起来的,配套文本导入工具/命令行功能。Oracle 的 sqlldr ; MySQL 的 LOAD DATA ; PG 的 COPY FROM 等等。原生直接对接数据库,速度快,不用再研发。数据库运维掌握这些工具是必备技能,出了啥问题也是运维和数据库公司支持方面搞定。(其实多少也是为了研发可以推点活到运维吧)
mengzhuo
2023-09-15 22:35:52 +08:00
@matepi 那也很可怕了……注入了解一下?输入数据必须经过程序完全转义和校验以后才能进入数据库的,真是不怕一锅端。
matepi
2023-09-18 10:36:27 +08:00
@mengzhuo 这正是用各类 loader 工具而不用自己代码程序的好处,各类 loader 工具和程序 sql 的差异了解下?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/973949

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX