0%

问题

想从 input 输入框中拿到文件流,转换为 blob 的数据

解决

StackOverflow 上的

···html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

```js
var input = document.querySelector('input[type=file]');
var textarea = document.querySelector('textarea');

function readFile(event) {
textarea.textContent = event.target.result;
console.log(event.target.result);
}

function changeFile() {
var file = input.files[0];
var reader = new FileReader();
reader.addEventListener('load', readFile);
reader.readAsText(file);
}

input.addEventListener('change', changeFile);

MDN 示例

1
2
<input type="file" onchange="previewFile()"><br>
<img src="" height="200" alt="Image preview...">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function previewFile() {
const preview = document.querySelector('img');
const file = document.querySelector('input[type=file]').files[0];
const reader = new FileReader();

reader.addEventListener("load", function () {
// convert image file to base64 string
preview.src = reader.result;
}, false);

if (file) {
reader.readAsDataURL(file);
}
}

还有个方法是 createObjectURL

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

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>URL.createObjectURL example</title>
</head>
<body>
<h1>GeeksforGeeks</h1>
<input type="file">
<img>
<p class="p">The URL of this image is : </p>
</body>
<script>
var Element = document.querySelector('input');
var img = document.querySelector('img');
Element.addEventListener('change', function() {
var url = URL.createObjectURL(Element.files[0]);
img.src = url;
console.log(url);
var d=document.querySelector(".p");
d.textContent+=url;
});
</script>
</html>

参考文章

记一下 JS 通过 input 加载 pdf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Step 1: Get the file from the input element
inputElement.onchange = function (event) {
var file = event.target.files[0];

//Step 2: Read the file using file reader
var fileReader = new FileReader();

fileReader.onload = function () {
//Step 4:turn array buffer into typed array
var typedarray = new Uint8Array(this.result);

//Step 5:pdfjs should be able to read this
const loadingTask = pdfjsLib.getDocument(typedarray);
loadingTask.promise.then((pdf) => {
// The document is loaded here...
});
};
//Step 3:Read the file as ArrayBuffer
fileReader.readAsArrayBuffer(file);
};

另外一个方法,好像都差不多,不过上面的方法传值不是 { data: myData }

1
2
3
4
5
6
7
8
9
10
var reader = new FileReader();
reader.readAsArrayBuffer(input.files[0]);
reader.onload = function (e) {

var myData = new Uint8Array(e.target.result)
var docInitParams = { data: myData };

PDFJS.getDocument(docInitParams).then(function(pdf) {.....})

}

参考文章

1
2
3
4
5
6
7
const findData = await Assets.findOne({
where: {
barCode: {
[Op.like]: `%${getCode}%`,
},
},
});

sqlite3 就不必多介绍了,讲一下今天踩的几个坑和解决方案

https://github.com/TryGhost/node-sqlite3

Electron 中使用 sqlite3

最小安装用例,package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"name": "sqlite3",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"electron": "^18.1.0",
"electron-builder": "^23.0.3",
"sqlite3": "^5.0.4"
},
"scripts": {
"start": "electron .",
"postinstall": "electron-builder install-app-deps"
}
}

直接运行 npm i 或者 yarn 安装依赖

非常好用的自己命令行编译的方法

方法一:官方的安装方法

--target=18.1.018.1.0 改成自己的 Electron 版本号

1
npm install sqlite3 --build-from-source --sqlite_libname=sqlcipher --sqlite=`brew --prefix` --runtime=electron --target=18.1.0 --dist-url=https://electronjs.org/headers

方法二,先下载,后编译

1
2
3
4
npm install node-gyp -g
npm install sqlite3 --ignore-scripts
cd node_modules/sqlite3
node-gyp rebuild --target=16.0.6 --arch=arm64 --dist-url=https://electronjs.org/headers --module_name=node_sqlite3 --module_path=../lib/binding/napi-v3-darwin-arm64

之所以加上 --ignore-scripts,是因为 sqlite3 模块在 package.json 文件中写了下载时自动执行编译的脚本,如下:

1
2
3
4
"scripts": {
"install": "node-pre-gyp install --fallback-to-build",
......
}

方法三,参数更全,自己配置 node-gyp 执行脚本路径等,具体参数需要看 node-gyp 的文档

1
"/opt/homebrew/Cellar/node/17.5.0/bin/node" "/Users/username/Documents/Temp/sqlite3/node_modules/node-gyp/bin/node-gyp.js" "configure" "--fallback-to-build" "--module=/Users/username/Documents/Temp/sqlite3/node_modules/sqlite3/lib/binding/napi-v6-darwin-unknown-arm64/node_sqlite3.node" "--module_name=node_sqlite3" "--module_path=/Users/username/Documents/Temp/sqlite3/node_modules/sqlite3/lib/binding/napi-v6-darwin-unknown-arm64" "--napi_version=8" "--node_abi_napi=napi" "--napi_build_version=6" "--node_napi_label=napi-v6"

踩坑及解决方案

NodeJS 17 版本问题

头铁使用最新版本 NodeJS v17.x 时,sqlite3 安装失败,报错:

1
2
3
gyp: name 'openssl_fips' is not defined while evaluating condition 'openssl_fips != ""' in binding.gyp while trying to load binding.gyp
gyp ERR! configure error
gyp ERR! stack Error: `gyp` failed with exit code: 1

https://github.com/nodejs/node-gyp/issues/2534

官方说法是 Nodejs 17 版本对 openssl_fips 不太支持,或者说有复写操作。

https://github.com/nodejs/node-gyp/issues/2534#issuecomment-976089582

解决方法如下

https://github.com/nodejs/node-gyp/issues/2543#issuecomment-1072104626

  • node-gyp 在本地安装最新的:
1
npm install -d node-gyp@latest

binding.gyp 中,添加(在顶部):

1
2
3
4
5
6
7
{
"variables": {
"openssl_fips" : "0"
},

...
}

但是我认为最好的办法是降回正式 16.x 版本

Homebrew 问题

如果你用 Homebrew 安装了 Nodejs,那么编译的时候参数会有所变化,多出一些参数

1
"/opt/homebrew/Cellar/node/17.5.0/bin/node" "/opt/homebrew/bin/npm" "install" "sqlite3" "--build-from-source" "--sqlite_libname=sqlcipher" "--sqlite=/opt/homebrew" "--runtime=electron" "--target=18.1.0" "--dist-url=https://electronjs.org/headers"

会多出一个 "--sqlite=/opt/homebrew" 的参数,而你电脑上没装 sqlite3 就会产生报错导致编译失败。

解决方案,Homebrew 或者 brew 卸载 Nodejs,用官方的 Nodejs 安装包重新安装

其他

Mac 卸载 Nodejs

编译 Electron sqlite3

Mac 卸载 Python

问题

NestJS debug 调试

解决

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "My application Name",
"runtimeArgs": ["--nolazy", "-r", "ts-node/register"],
"args": ["${workspaceFolder}/src/main.ts"],
"autoAttachChildProcesses": true
}
]
}

参考文章

1
2
3
4
5
6
7
8
9
10
11
function isValidHttpUrl(string) {
let url;

try {
url = new URL(string);
} catch (_) {
return false;
}

return url.protocol === 'http:' || url.protocol === 'https:';
}
1
2
3
4
5
6
7
8
9
10
11
12
function validURL(str) {
var pattern = new RegExp(
'^(https?:\\/\\/)?' + // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
'(\\#[-a-z\\d_]*)?$',
'i'
); // fragment locator
return !!pattern.test(str);
}
阅读全文 »

问题

后端对提交的数据进行了一些转义操作,比如 <p><b>123&456</b></p> 这样的,会被转义成 &lt;p&gt;&lt;b&gt;123&amp;456&lt;/b&gt;&lt;/p&gt;

然后前端请求数据时,这些数据需要反转义一下

解决

这是我目前用到的,不必担心性能问题,见后面的研究部分。

1
2
3
4
5
6
7
8
// 反转义 bug@&amp; 这样的字符
export function HTMLDecode(text) {
var temp = document.createElement('div');
temp.innerHTML = text;
var output = temp.innerText || temp.textContent;
temp = null;
return output;
}
阅读全文 »

问题

NestJS 接收单个文件的上传和批量多个文件上传,及上传文件添加额外参数

解决

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
33
import {
Controller,
Post,
Body,
UseInterceptors,
UploadedFile,
UploadedFiles,
Request,
UseGuards,
StreamableFile,
Get,
Response,
Param,
} from '@nestjs/common';
import { FileInterceptor, FilesInterceptor } from '@nestjs/platform-express';

// 单文件 + 其他字段
@Post('uploadPdf')
@UseInterceptors(FileInterceptor('pdf', { dest: './uploads' }))
async uploadPdf(@UploadedFile() file, @Body() body) {
console.log(file, body);
}

// 多文件 + 其他字段
@Post('upload')
@UseInterceptors(FileFieldsInterceptor([
{ name: 'avatar', maxCount: 1 },
{ name: 'background', maxCount: 1 },
]))
uploadFile(@UploadedFiles() files: { avatar?: Express.Multer.File[], background?: Express.Multer.File[] }) {
console.log(files);
}

参考文章

想做一个对象检测,和自己训练模型,目前处于查资料状态,还未开始。