Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Axios serving png image is giving broken image

I am using express as middle-ware api.A person hits my middle-ware , it hits some third party api and returns back the result. Its working fine for all other end points expect an get end point that creates an png and serves it. so under method returns response

   _execute = R.curry((reqFunction, req, res) => {
        reqFunction(req, res).
        then(r => {
          res.status(r.status).header(r.headers).send(r.data)
        }).
        catch(err => {
          res.status(err.response.status).header(err.headers).send(err.response.data)
        })
      });

and reqFunction is method like

  modelDiagram = (req, res) => {
    const headers = req.headers;
    const modelName = req.params['modelName'];
    const endPoint = this.modelDiagramEndPoint + '/' + modelName;
    return this.httpRequests.get(endPoint, headers);
  }

and httpRequests.get method is

  get = (endPoint, headers) => {
    let options = {
      method: 'GET',
      url: endPoint
    }
    options = this.addHeaders(headers, options);
    return this._send(options);
  }

and this._send is like

  _send = (options) => {
    return axios(options);
  };

the response if I directly hit from browser is like ``` �PNG

IHDRn��7Q� IDATx���oHk����D�ȥ|!H�DD�^)"k"n�̤$H�V뒻�Vж"�+��n-"�[��X񲻝L��լ�[Z�^����lnK&K���=�9�9z�sʋs�~���g�g��g����gf��l��z��QIcc�dEE�<��?�\YY�վ}�R7!{�����'O�T�C�x�B�fff��۷UYYٿ8��^�a� ������?��92O��L2w�����{���s�NXZ��k۝N�r�\�<.�N������/_���尵�����ϫ���E�['���"�x˞|f ���~��N��K�d�����u���3j��u5�����%p6���Sj���ꛎ3>�<)�M�M�y4���v��ܳ{� N�gSpCw~��p�[Opr��Φ�F��M@pR8��[�z������ä'O�g����-+�I7�v�����oW��<)� �ɓ�|�p��2;<=�)�fF;Փ��4 4ò�����8Qf����V�,X�n��},4À���H�8�n}}�������8"���À7p�/]��j����h�0g�@Bfપ�Too/������z��mD� 8���Ḹ8�w�^������v�ڵ��v�ܩ��������ݭˬgX�ۺu���� x@###:��N(�Ο?��o߮6o޼�'YSS�n߉'|����Tcccx����P���::Z����h1�v�U~~����Q)))����9�V;�[�n�tAA����U����l+P$O�[��̙3�3׹Z[���|)�ϯ��WIII>>^ |���7o�q�~��RzYT��q��@�]7p2���ZZZ�Ç}v^TT��Feee<��0�;v�P�����o�U[[�����e�� ���Q������m]]��,//ϻ~EE��3"��ի���<h���[���Έ����;��.Y^��SYY��l�'X�ն�񤥥��j����4##C/���{��@u�.P{� �Ѹ;7����9�a58����j[���u����3�Ȝ'��Zu~8��������{���ӧO��\�IWWW�lc̃����6Z�sIo۶Mϛ�p��ޮӒ'�+��3P[�yH�|e����e���аf�����+鱱1UZZj���N����T}�577���r���F�A����1b�b����R��0�O�拓@e���-�C%&&�mUTTԚO��$e�H1��ӿ���A}A#?��������H�����#�&7bo�%z�̐3/77W�>��#/8�a�a�p�ÀÀ�88:�Hyz�x��[�].�L$|w <55����tvv����z=77���۸HhN��;�_�yV��!�@o�l��ߟ���Y!�!�ppp�C�C����888�!�!�!�pppp�C�C������8zppp��)�>w�����k��[V��N�S�\�W�X'�zzz/��X���ˇ�-��W" h���l�-�|w�v��������hy06���|�N1Կ�jDM/�����'�����/՝��5��w�[:���Hr�zc �����η�37��C��U����8�a�pNn�C�ƍ�M�ɣ�P����&��a�<�����|�ppp��0�8�a�a�.���xb;u���8���k׮��?�\EEE�t��I���*))I��ǫ��]6;;����Ull����Q���3��|��ƍ�zU\�.����y���z���W���+�����W�Ѽ�v���RGJJ�ONN���推���!鼼<]��7ܪ��M[Ғglk�9uꔷ��������kjjt^UU�^>wr�����}&$$����H�GFF��YYY�.77W�t���d�aɼl�^ZZ�6"�XwϞ=:��@qYY�Η��O�����T�,���cLKKS���A��}���8pi���^xN�Gcݒ�������N���ѣ�u233u~SS�>y����d�?11���dx��9���V-,,�5栵:�#�d{{�NK���1J}:-s��˗��HZ�e~mnn^1?ÜX���9$=66�JKK}�d��tuuu䂓�]�P����VK�$J�l'��y����X�����6�?::��dH4G���P�������B��&s�� Nr���O�\��� 8�0�0�8�a�a�p��8l'p��V^��t��5�w�ᩩ�/-w���sOWW�빹��t��E�@s:��Y�҇ȳ�n��|�fC,��,$h!�B!����?Ǔ�8���IEND�B� ```

but image is broken. I have tried many things like req.end and explicitly setting headers but I am not able to solve it.Please guide me

like image 653
Dhruv Pal Avatar asked Jan 04 '23 08:01

Dhruv Pal


1 Answers

Sorry for late answer but maybe someone find this approach more reliable:

axios.get('/path/to/image.png', { responseType: 'arraybuffer' })
.then(response => {
      let blob = new Blob(
        [response.data], 
        { type: response.headers['content-type'] }
      )
      let image = URL.createObjectURL(blob)
      return image
    })

How I understand this:

  1. When you specifies in options { responseType: 'arraybuffer' } axios will set response.data to ArrayBuffer
  2. Next you create file-like object - Blob
  3. You get url to blob-file via URL.createObjectURL(blob) that you can use in src attribute of img tag

As described in this article approach above should be faster.

Here is jsfiddle demo

UPD:

Just find out that you can specify in options responseType: 'blob' so you don't need to create Blob object yourself:

axios.get('https://picsum.photos/300/300', {responseType: 'blob'})
.then(response => {
  let imageNode = document.getElementById('image');
  let imgUrl = URL.createObjectURL(response.data)
  imageNode.src = imgUrl
})

Jsfiddle demo

Here axios issue about missing documentation for binary data manipulation. In this comment you can find the same approach that I suggest. Also you can use FileReader API, in this stackoverflow comment you can find pros and cons for both approaches.

like image 172
fotonmoton Avatar answered Jan 06 '23 22:01

fotonmoton