javascript - 读取 multipart/form-data 保存不正确
问题描述
我正在尝试从 http 图像文件上传中读取数据。它似乎读取了文件,但由于某种原因,输出文件的大小大约是原始文件的两倍。
原始文件:94.7KB
临时文件:168.8 KB
当我在文本编辑器中打开这两个文件时,它们的行数相同,并且起始字符和结束字符相同。这让我相信上传的文件被保存为字符串而不是二进制数据。
我认为重要的部分如下
数据读取:
let body = ''
req.on('data', data => {
body += data.toString()
}).on('end', data => {
if (data) body += data.toString()
// Rest of block
})
数据的保存:
// If there is a filename grab the file data
if (result.filename.length > 0) {
// Create a temporary url
let temp = join(os.tmpdir(), (Math.random() * 10000).toString(12).substr(5, 10))
// Get the data between the blocks after the first two newlines
let matches = item.match(/^.+?(\r\n\r\n|\n\n)(.+)/s)
// Write the data to file
fs.createWriteStream(temp).write(matches[2])
}
以下是数据的完整解析:
http.createServer((req, res) => {
let body = ''
req.on('data', data => {
body += data.toString()
}).on('end', data => {
if (data) body += data.toString()
let boundary = req.headers['content-type'].split('boundary=')[1]
// Split all the boundary items and loop over them
body.split(new RegExp(`(--${boundary}|--${boundary}--)`)).forEach(item => {
if (item.trim().toLowerCase().startsWith('content-disposition')) {
item = item.trim()
// Find the name and filename
let result = item.split(':')[1].split(';').map(i => i.trim()).reduce((obj, itm) => {
if (itm.startsWith('name=')) obj.name = itm.match(/^name="(.+)"/)[1]
if (itm.startsWith('filename=')) obj.filename = itm.match(/^filename="(.+)"/)[1]
return obj
}, { name: '', filename: '' })
// If there is a filename grab the file data
if (result.filename.length > 0) {
// Create a temporary url
let temp = join(os.tmpdir(), (Math.random() * 10000).toString(12).substr(5, 10))
// Get the data
let matches = item.match(/^.+?(\r\n\r\n|\n\n)(.+)/s)
// Write the data to file
fs.createWriteStream(temp).write(matches[2])
}
}
})
})
})
解决方案
所以,我在这两种情况下都是正确的......
首先,我必须像这样将数据读取为二进制数据:
body += data.toString('binary')
接下来保存时,我需要像这样保存为二进制数据:
fs.createWriteStream(temp).write(matches[2], 'binary')
现在保存为正确的文件大小并且图像可读!
推荐阅读
- javascript - 是否有 App 会在 React Native 中隐藏/显示?切换应用程序时删除键盘侦听器的问题
- python - Django 找不到模块“learning_logs”的问题
- docker - 从 Skopeo 容器访问本地 docker 注册表
- r - 如果它们降落在另一个点的某个附近,我如何生成点被“排斥”的数据?
- ajax - 使用 express 对谷歌云功能的 axios 请求
- javascript - 更改 [ ] 符号之间的样式的问题
- swift - 为什么 UITextFIeld 在 Swift 中返回可选值?
- javascript - Nginx(反向代理)和 Angular(使用 SSR 和 i18n) - 根据 lang cookie 值使用正确的本地化应用程序
- lldb - 为什么在 lldb 中的“命令别名 pcs 调用 ...”时出现“错误:无法创建请求的别名”?
- python - 计算回归变量的方差