Requesting Application / PDF generating file with wrong information [AngularJS + NodeJS]

0

I have a totally Restless AngularJs + Node (Express) application. The back-end serves only to validate requests and route to other applications, which have business rules.

At the moment, my front sends a request to generate a pdf, something like:

const callbackSucesso = function(resposta){                    
    if(resposta && resposta.data){
        let headers = resposta.headers();
        let blob = new Blob([resposta.data],{type: headers['content-type']} );
        saveAs(blob, "download.pdf");
    }else{
       //coisas que não importam aqui
    }
};
$http({
    method: 'POST',
    url: '/api/pdf',
    data: JSON.stringify(dto)
}).then(callbackSucesso,callbackErro);

However, when I open the generated file, I notice that there is information that is distorted, for example: DESCRIPTION = > DESCRIPTION

When done by postman, the API return is normally generated as a file.

I've already found answers that tell you how to add type information to the Blob object - such as this: Generate angled pdf using javascript - but the error has been retained.

When I tried to do in the back end, the outputs were not very different. Then I thought about intercepting the node, generating the file, and redirecting it to the front.

   const fs = require('fs');
   ...
   request(options, function(error, resposta, corpo){
        if(error) {
           //não interessa para o contexto
        }else{
            fs.writeFileSync("10111.pdf", corpo,'binary');
           //aqui eu enviaria o link pro front baixar
        }
        next();
    }); 

I followed this example here: link

Thank you in advance to anyone who can clear my road (!)

    
asked by anonymous 17.02.2018 / 01:22

1 answer

0

I found the solution as follows:

In the backend, which I mentioned was just a router, I chose to change it to this endpoint, in order to receive the request that it redirects as follows:

    //Gero minha requisição
        let options = gerarRequisicao("POST", endpointASerRedirecionadaARequest, req);
    //Crio um array para ir concatenando os valores recebidos via stream
        let pdf_buffer = []; 
    //Callback que será invocado ao completar a request. Observe que não utilizo o "body" que é fornecido, e sim o que  fui armazenando 
        const aoCompletar = (resposta,body) => { 
            // Aqui, concateno todos os valores que foram bufferizados.
            let data = Buffer.concat(pdf_buffer);
            resp.status(resposta.statusCode).json(data.toString('base64'));
        };

        request(options)
 /*Cada parte que recebo do meu stream, será adicionada no meu buffer, 
   que será utilizado no callback aoCompletar*/
            .on("data", d => pdf_buffer.push(d) )
            .on("complete", aoCompletar)
            .on("error", e => resp.status(500).json(geraMensagemDeErro(e)) );
        });

It seems to me that the value that is received as the body of the request via parameters in the callback used at the time of the question seems to be incomplete or something like that.

I took the liberty to send back to the front as base64 to ensure my requests.

On the front, when I receive the response, I convert the body to an array, play on a blob and download it:

const callbackSucesso = function(resposta){                    
    if(respostaEstaValida(resposta)){
        let cabecalho = resposta.headers();
        let arquivo = converterBase64ParaBlob(resposta.data, cabecalho['content-type']);
        saveAs(arquivo, "download.pdf");
    }else{
        //não interessa para o contexto
    }
};
$http({        
    method: 'POST',
    url: '/api/pdf',
    data: JSON.stringify(dto)
}).then(callbackSuceso,callbackErro);     

Finally, the conversion takes place as follows:

function converterBase64ParaBlob(base64, contentType){
    let respostaBruta = window.atob(base64);
    let tamanhoDaResposta = raw.length;
    let cache = new Uint8Array(new ArrayBuffer(tamanhoDaResposta ));
    for(let i = 0; i < rawLength; i++) {
        cache[i] = respostaBruta.charCodeAt(i);
    }
    let blob = new Blob([cache],{type: contentType} );
    return blob;
  }
    
17.02.2018 / 19:54