Javascript 如何将字节数组转换为base64编码格式?

Javascript 如何将字节数组转换为base64编码格式?,javascript,blob,bytea,Javascript,Blob,Bytea,我有一个页面可以从Postgres数据库下载一个文件。现在,我可以点击以下URL查看数据库中存在的文件内容(存储为字节)-HTTP://sandbox4.wootz.io:8080/api/blob/1/UploadFile/hope%20real.txt 由于当我单击下载按钮时,数据存储在字节(字节数组)类型的列中,因此它将下载文件,当我看到其内容时,它将显示为字节数组 txt文件(目录) 下载功能 axios({ url: 'api/store/blob/UploadFile

我有一个页面可以从Postgres数据库下载一个文件。现在,我可以点击以下URL查看数据库中存在的文件内容(存储为字节)-HTTP://sandbox4.wootz.io:8080/api/blob/1/UploadFile/hope%20real.txt

由于当我单击下载按钮时,数据存储在字节(字节数组)类型的列中,因此它将下载文件,当我看到其内容时,它将显示为字节数组

txt文件(目录)

下载功能

  axios({
      url: 'api/store/blob/UploadFile/' + data.chosenfile,
      method: 'GET',
      headers: {'session_id': data.sessionid},
      responseType: 'arraybuffer'
    }).then(response => {
console.log(response.data); //displays nothing (empty)
var fileURL = window.URL.createObjectURL(new Blob([response.data]));
      console.log('fileURL is'+fileURL)
      var fileLink = document.createElement('a');
      console.log('fileLink is'+fileLink)
      fileLink.href = fileURL;
      fileLink.setAttribute('download', data.chosenfile);
      document.body.appendChild(fileLink);
      fileLink.click();
)

响应对象的console.log

{"data":{},"status":200,"statusText":"OK","headers":{"access-control-allow-origin":"*","connection":"keep-alive","content-length":"86","content-type":"text/html; charset=utf-8","date":"Mon, 06 Jul 2020 18:22:23 GMT","etag":"W/\"56-Vaz0hG1/FIgtEurgvK+wOU+4F4M\"","x-powered-by":"Express"},"config":{"url":"api/store/blob/UploadFile/hope real.txt","method":"get","headers":{"Accept":"application/json, text/plain, */*","Access-Control-Allow-Origin":"http://localhost","session_id":"c5b3b878-771e-4472-84eb-6de15686effa"},"transformRequest":[null],"transformResponse":[null],"timeout":0,"responseType":"arraybuffer","xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1},"request":{}}
Uploadfile是我代码的一部分(这是文件上载到数据库的方式)

我做错了什么?为什么我将文件内容获取为[\X58595A5052415445454B3123473B4C534E442044E474F4957457485347494447445348474D7025335]?我应该如何在下载的文件中获取实际文件的内容


注意:关于上传部分,我对所有类型的文件(excel文档、txt文件等)使用相同的策略,在将其传递到axios post负载之前将其编码为base64编码字符串。现在,该负载被传递到另一个名为data manager的项目(与postgres数据库交互)。因此,当此data manager项目接收到我发送的有效负载时,它会将其转换为字节[],然后再插入到类型为bytea的表列中。因此,最终当我从该表下载任何文件时,我将获得同样为bytea格式的文件内容。

您的文件是一个内容正确的ASCII文本文件
[\X58595A5052415445454B3123473B4C5344E442042404E474744F49574534748574849444748445348474D7025335]
字面意思。
当你下载它的时候,你可以得到这个内容,因为它就是这个文件的内容

您要做的是将内容从他们使用的十六进制表示形式解析到实际的ArrayBuffer,最终以UTF-8文本(或任何有关ASCII的编码)的形式再次读取

这必须在下载文件并将其作为文本阅读后进行。
首先从该
[\x
-
]
包装器中提取实际字节序列作为十六进制,然后在每两个字符处拆分结果字符串以获得每个字节的十六进制值,最后将其解析为Uint8Array以获取原始数据:

//对于StackSnippet,我们需要硬编码响应
//OP必须使其请求返回该字符串
常量响应={data:String.raw`[\X58595A5052415445454B3123473B4C534E442044E474F4957457485347494447445348474D7025335]`;
//。然后((响应)=>{
const encoded_text=response.data;
//删除前导“[\x”和结尾“]”
const encoded_data=encoded_text.slice(3,-1);
//每两个字符拆分一次,这样我们就可以得到0xNN,0xNN
const hex_bytes=encoded_data.match(/.{2}/g);
//作为数字(0-255)
const num_bytes=hex_bytes.map((hex)=>parseInt(hex,16));
//在Uint8Array中换行
const view=新的Uint8Array(num_字节);
//从那里,您可以生成要保存在磁盘上的Blob
下载(新Blob([view]),“file.txt”);
//但如果您想将其作为UTF-8文本阅读,您可以:
const as_text=新文本解码器()。解码(视图);
console.log(作为文本);
// } );
函数下载(blob,文件名){
const-anchor=document.createElement(“a”);
anchor.href=URL.createObjectURL(blob);
anchor.download=文件名;
anchor.textContent=“单击下载”;
document.body.append(锚定);

}
当我将
data.chosenfile
更正为
response.data.chosenfile
时,删除
responseType:'arraybuffer'
,并硬编码URL(因为我无法验证
data.chosenfile
是否正确),它对我来说很好。您希望得到什么输出?
XYZPRATEEK1#G;LSND NGOIWHSGHIDGHDSHGMp%35
?其他内容?是的,我希望XYZPRATEEK1#G;LSND NGOIWHSGHIDGHDSHGMp%35作为输出内容。我应该怎么做才能在下载的文件中获得此输出?这对于文本文档很好,但在数据库中我还有其他亲属d个文件(excel文档等),它们实际上是使用reader.readAsDataURL(文件)编码为base64格式的;从这个base64 url中,我使用resolve(base64String.substr(base64String.indexOf(','))+1)只提取了url部分,而没有提取头;为什么不对这两种文件使用相同的策略?(要么全部到b64,要么全部到十六进制).你怎么知道哪个已经转换成b64,哪个已经转换成十六进制?我在这里帮不了你多少忙…从b64转换也很容易,而且已经有很多答案了,但我认为你在这里面临着一个只有你才能解决的更基本的设计问题。我已经用上传文件部分更新了我的问题。请原谅se help?您无法从编辑中的代码中获得您所说的结果。请回滚此编辑,如果您有比我已经回答的更多的问题,请询问其他问题。Ps:我的代码可以处理任何二进制数据,其编码方式与您在问题的第一次修订中所说的编码方式相同。
{"data":{},"status":200,"statusText":"OK","headers":{"access-control-allow-origin":"*","connection":"keep-alive","content-length":"86","content-type":"text/html; charset=utf-8","date":"Mon, 06 Jul 2020 18:22:23 GMT","etag":"W/\"56-Vaz0hG1/FIgtEurgvK+wOU+4F4M\"","x-powered-by":"Express"},"config":{"url":"api/store/blob/UploadFile/hope real.txt","method":"get","headers":{"Accept":"application/json, text/plain, */*","Access-Control-Allow-Origin":"http://localhost","session_id":"c5b3b878-771e-4472-84eb-6de15686effa"},"transformRequest":[null],"transformResponse":[null],"timeout":0,"responseType":"arraybuffer","xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1},"request":{}}
function readFileAsync(file) {
  return new Promise((resolve, reject) => {
    let reader = new FileReader();

    reader.onload = () => {
      var base64Url = reader.result; 
      console.log(base64Url) //ENITRE BASE64 URL 
     
     
      resolve(base64Url.substr(base64Url.indexOf(',') + 1)); //will return only the base64string part from the base64 url
    };

    reader.onerror = reject;

    reader.readAsDataURL(file); 
  })
}

async function uploadFile(path, data) {
  try {
    
    let base64string = await readFileAsync(data.chosenfile);
    console.log('base64 content  is'+ base64string)

    let response = await axios({
      method: 'post',
      url: 'api/store/blob' + path,
      headers: {'session_id': data.sessionid},
      data: {"id":data.chosenfile.name, "file":   base64string }
    });    

    if (response.status == 200) {
      console.log(response.status);
    }
    return response.data;
  } catch (err) {
    console.error(err);
  }
}