Javascript 如何将通过浏览器上传的文件转换为字节?

Javascript 如何将通过浏览器上传的文件转换为字节?,javascript,file-upload,byte,Javascript,File Upload,Byte,我需要上传一个图像(对象)到服务器作为一个字节。用户通过输入字段将图像上载到浏览器 我的问题是图像必须转换成字节,我找不到如何在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\

我需要上传一个图像(对象)到服务器作为一个字节。用户通过输入字段将图像上载到浏览器

我的问题是图像必须转换成字节,我找不到如何在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)

我找不到如何将
imageFile
直接转换为
imageFile
->base64->字节。

我认为这是一个XY问题,因为您实际上想知道如何将文件直接传递到请求中,而在如何将base64转换为字节的问题上,您已经走错了路。所以最好退一步,因为有一个更直接的解决方案

我在这里看到两个问题:

  • 您正在以数据URL的形式读取文件,即使您需要原始格式的文件。我的建议是改用。但实际上,您根本不需要读取或转换数据,只需将
    imageFile
    直接传递到
    axios.put
    。这应该是可行的,因为axios接受
    Blob
    s作为主体

  • 您正在将
    {data:result}
    而不仅仅是
    result
    作为主体参数传递给
    axios.put
    。结果是,axios将看到一个带有key
    data
    和一些值的对象,并尝试对其进行编码,但实际上您似乎是在尝试直接上传原始文件(也根据您的
    内容类型
    )。因此,简单地使用
    axios.put(url,theData,{headers:…})
    而不是
    axios.put(url,{data:theData},{headers:…})
    应该可以解决这个问题

  • 顺便说一下,您也可以从
    imageFile.type
    获取内容类型,而不是硬编码内容类型


    底线是以下代码应该可以工作:

    const urlToUploadFile='url由服务提供'
    const imageFile=文件[0]
    等待axios(
    urlToUploadFile,
    图像文件,
    {标题:{‘内容类型’:imageFile.Type}
    )。然后(响应=>{
    console.log('响应:',响应)
    })
    
    您是否尝试使用
    readAsArrayBuffer
    而不是
    readAsDataURL
    ?应该这样做。(也有
    readAsBinaryString
    但是如果可能的话最好使用数组缓冲区,axios应该可以。)或者你在使用数组缓冲区时有任何错误吗?@CherryDT Yeap。使用readAsArrayBuffer
    reader.result
    看起来像:ArrayBuffer(67541){}[[Int8Array]]:Int8Array(67541)[-119,80,…][[Uint8Array]]:Uint8Array(67541)[137,80,…]上传大小是11B,而这应该是90KB左右。
    reader.result
    看起来不错。但是我认为您需要简单地传递
    result
    ,而不是
    {data:result}
    。因为在传递JSON时,
    result
    字符串化为一个无意义的字符串,如
    [object ArrayBuffer]
    。实际上,您甚至不必首先读取数据,请检查如果您只传递
    imageFile
    本身,即
    axios.put(urlToUploadFile,imageFile,{headers:…})会发生什么情况
    @CherryDT谢谢,两种方式(
    reader.readAsArrayBuffer+result而不是{data:result}
    和简单的
    axios.put(urlToUploadFile,imageFile,{headers:…})都可以工作。关于
    {data:result}
    的问题如此愚蠢,请发布答案让我接受。
    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)