javascript - 如何将通过浏览器上传的文件转换为字节?
问题描述
我需要将图像(File对象)作为字节上传到服务器。图像由用户通过输入字段上传到浏览器。
我的问题是图像必须转换为字节,我找不到如何在 JS 中完成。
下面是可以正常工作的python代码。
response_with_image = requests.get('some-url.png')
bytes_of_image = response_with_image.content # ->> b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x03R\x00\x00\x02\xbc\x08\x02\x00\x00\x00j}\x19\x16\x00\x00\x00\tpHYs\x00\x00\x0fa\x00\x00\x0fa\x01\xa8?\xa7i\x00\x00 \x00IDATx\x9c\xec\xbd\xbf\xcbuKr\x1eZ\xfd\xce\t,s\xb9\xfa\x17\x8ep\xa2@X\xe0\xbf`\x06\'g\xb8\xa9\xfe\x02i\x12#\xb8\xd1\x0c\x0e\'6\x9a\xe4\xfe0JfP$.\xf7"Pdt\x121\x03J\x84\xc0\xd8\xe0\t&\x11:\x18\x8c\x13e\x86\x19\x07:\xbbo\xf0~o\x9fZ\xf5<\xf5tu\xaf\xbd\xdf\xef\xdb3\xabh\x9a\xa7\xaa\xab\xaa{U\xf7\xea\xae\xd3\xeb\xdd\xdfi\xbdw\xbb\xe8\xa2\x8b.\xba\xe8\xa2\x8b.\xba\xe8\xd7\x9d^>\xf6......'
r = requests.put(url_to_upload_file, headers={"Content-Type": "image/png"}, data=bytes_of_image)
目前我可以用 JS 实现的最佳效果如下 - 代码创建了一个大小不正确(90 KB 而不是 66 KB)和正确类型的文件。当我检查上传的文件时,浏览器不会将其识别为图像,显然是因为我上传的是 base64 而不是字节。
const urlToUploadFile = 'url-provided-by-service'
const imageFile = files[0]
const reader = new FileReader()
reader.onloadend = function () {
const result = reader.result // data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAsUAAAQJCAYAAAAuMXXtAAAgAElEQVR4nOzdfWxTd573/f6....
await axios.put(
urlToUploadFile,
{ data: result },
{ headers: { 'Content-Type': 'image/png' } }
).then(response => {
console.log('response:', response)
})
reader.readAsDataURL(imageFile)
我找不到如何imageFile
直接转换为imageFile
-> base64 -> 字节的字节。
解决方案
我认为这是一个 XY 问题,因为您实际上想知道如何将文件直接传递到请求中,以及如何将 base64 转换为字节的问题,您已经走错了路。所以最好退后一步,因为有一个更直接的解决方案。
我在这里看到两个问题:
即使您需要原始格式的文件,您也正在将文件作为数据 URL 读取。我的建议是
readAsArrayBuffer
改用。但实际上您根本不需要读取或转换数据 - 您可以imageFile
直接将axios.put
. 这应该有效,因为File
继承自Blob
并且 axios 接受Blob
s 作为主体。您正在传递
{ data: result }
而不是result
作为正文参数传递给axios.put
. 结果是 axios 将看到一个带有键data
和一些值的对象并尝试对其进行编码,但实际上您似乎正在尝试直接上传原始文件(也根据您的Content-Type
. 因此,显然使用axios.put(url, theData, { headers: ... })
而不是axios.put(url, { data: theData }, { headers: ... })
应该修复它。
顺便说一句,您也可以从imageFile.type
.
底线是以下代码应该可以工作:
const urlToUploadFile = 'url-provided-by-service'
const imageFile = files[0]
await axios.put(
urlToUploadFile,
imageFile,
{ headers: { 'Content-Type': imageFile.type } }
).then(response => {
console.log('response:', response)
})
推荐阅读
- python - 在滚动函数上迭代窗口大小,附加到新的数据框?
- r - 通过 Rstudio 在远程服务器上运行 R 代码,而不是通过浏览器
- c# - Clr 如何知道类/字段定义的 il 代码在哪里?
- java - 如何使用 Project Reactor 设计/创建反应方法
- swiftui - 在 SwiftUI 中显示具有指定小数位的浮点数
- javascript - 如何知道 Javascript 中的哪些代码更改或访问了对象中的属性?不是 DOM 对象
- javascript - NodeJS中的可读连接流?
- reactjs - 为什么我的 getImageId 函数只在我的代码第一次运行时触发?
- linux - 尝试学习eBPF尾调用,无法附加kprobe
- grails - Grails 3 中的下拉列表