如何使用 axios 和文件编码将多个 byteIO 文件从 Flask 端点发送到 Vue

How to send multiple byteIO files from Flask endpoint to Vue using axios and file encoding

TL;DR

烧瓶:

docx --> bytesIO --encodebytes()--> bytes --decode()--> string --> array 包含这些字符串的多个。

视觉:

array 包含那些字符串 --?--> blob


问题

我正在尝试 return 将多个 byteIO 文件从 Flask 端点一次发送到我的 Vue 应用程序。

基于,可以通过使用bytesencode() 和.decode() 将byteIO 文件转换为字符串来完成。 然后将字符串附加到数组并 json 序列化。

我不知道如何完成,但是要将 Vue 中的转换反转回必要的 blob 对象(将被下载)。

关于如何完成此任务有什么建议吗?

我如何从 docx 模板创建我的 bytesIO 文档文件(我的代码深受 的启发):

def from_template_multiple(context): # context is a dict containing custom attributes to be rendered in the document

    template = DocxTemplate(template_document.docx')

    # Create in-memory buffer
    target_file = BytesIO()

    # Render template and save to the buffer
    template.render(context)
    template.save(target_file)

    # Reset the buffer's file-pointer to the beginning of the file
    target_file.seek(0)
 
    # return target file instead of send_file directly
    return target_file

我的 flask 路由接收 axios 调用,从 Vue 接收上下文属性。文件编码部分来自this answer.

@hagis_api_bp.route('/docx/multiple', methods=['POST'])
def generate_word_multiple():
    request_json  = request.get_json()

    # array to store blob derivations
    blob_array = []

    for item in request_json['body']:
        context = json.loads(item)
        target_file = process.from_template_multiple(context)

        # encode as base64
        from base64 import encodebytes
        encoded_file = encodebytes(target_file.getvalue()).decode('ascii')

        # append target file to blob array
        blob_array.append(encoded_file)

    return jsonify({'result': blob_array})

最后是 Vue 部分。此 axios 调用用于发送上下文信息 (json),在这里我想 return blob_array 然后恢复编码过程以接收“原始”blob 文件。

    // axios request + file download
    axios({
      url: 'docx/multiple',
      data: {body: body_array},
      method: 'POST',

    }).then((response) => {
        // looping over each element in response.data (each converted bytesIO string)
        response.data['result'].forEach((element) => {
        
        // convert string to blob here ?
        
        // download blob as docx file
        const url = window.URL.createObjectURL(new Blob([converted_element])); // --> using result from missing conversion above
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download', 'title.docx');
        document.body.appendChild(link);
        link.click();
      });
    });

我能够解决问题。以下 axios 请求可以解决问题。 这个问题很有帮助:Creating a BLOB from a Base64 string in JavaScript

// axios request + file download
        axios({
          url: 'docx/multiple',
          data: {body: body_array},
          method: 'POST',

        }).then((response) => {
          response.data['result'].forEach((element) => {
            console.log(element)

            // decode string to blob --> solution to question
            const byteCharacters = atob(element);
            const byteNumbers = new Array(byteCharacters.length);
            for (let i = 0; i < byteCharacters.length; i++) {
              byteNumbers[i] = byteCharacters.charCodeAt(i);
            }
            const byteArray = new Uint8Array(byteNumbers);
            console.log(byteArray)

            const url = window.URL.createObjectURL(new Blob([byteArray]));
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', 'test.docx');
            document.body.appendChild(link);
            link.click();
          });
});