服务png图像的Axios正在提供损坏的图像

时间:2017-03-14 11:50:23

标签: javascript es6-promise axios ramda.js

我使用快递作为中间件api。一个人击中我的中间件,它击中一些第三方api并返回结果。它对所有其他端点的工作正常,期望得到一个结束点,创建一个png并为其服务。 所以在方法下返回响应

   _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)
        })
      });

reqFunction是类似

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

httpRequests.get方法

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

和this._send就像

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

如果我直接从浏览器点击的响应是这样的 ``` PNG

IHDRn7Q !IDATxoHkDȥ| HDD ^) “K” N $ HV뒻Vж “+ N - ”[XLլ [Z ^&LNK放大器; K =99zsʋs〜ggggflzQIccdEE&LT ; ? \YY վ} R7!{ 'O T C x B fff 7UYYٿ8 ^ a ? 92O上述L 2w {sNXZk۝N T个\&LT; .N / _尵ϫ E [' “ x˞|f ~ N K d u 3j u5 %p6 Sj ꛎ3&GT;≤)MMy4vܳ{ NgSpCw〜P [OprΦFM@ PR8 [zä'Og-+ I7v OW≤) ɓ | p 2;&lt; = ) fF;Փ 44ò 8Qf V ,X n },4ÀH 8 N}} 8" À7p/] jh0g @了Bfપ太/ ZMD 8Ḹ8w^ VڵvܩݭˬGXۺü X @ ###:N(Οö߮6ö޼ 'YSSn߉' | TcccxP :: Zh1v Ù~~ Q)))9V; [ntAAUl + P $ -O [33׹Z [ |)ϯWIII&GT;&GT; ^ | 7oq〜RzYTq @]7p2ZZZÇ}伏^ TTFeee℃,; VPO U [[e�� ���Q������m]]��,//ϻ~EE��3"��ի���<h���[���Έ����;��.Y^��SYY�� L'XնJ4 ## C / {@ u.P { Ѹ;7�� 9a58j [U3 Ȝ'Zu〜8 { ӧO\IWWWlc6ZsIo6MςpޮӒ'+ 3P [yH的|eeаf+鱱1UZZj NT} {577r {1}} 3 |ƍzU\ .yzW +WѼvRGJJONN推鼼&LT;!] 7ܪM [Ғglk9uꔷkjjt^ UU ^&GT;wr}&安培; $$HGFFYYY.77Wtdaɼl^ ZZ6" XwϞ=: @qYYΗOT,cLKKSA ��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�� ```

但图像被破坏了。我尝试过很多像�}���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这样的事情并明确设置标题,但我无法解决它。请指导我

2 个答案:

答案 0 :(得分:0)

你试试这个

return axios.get(<URL WHICH RETURNS IMAGE IN STRING ex:'http://host/image.png'>, { responseType: 'arraybuffer' })
  .then((response) => {
    let image = btoa(
      new Uint8Array(response.data)
        .reduce((data, byte) => data + String.fromCharCode(byte), '')
    );
    return `data:${response.headers['content-type'].toLowerCase()};base64,${image}`;
  });

答案 1 :(得分:0)

很抱歉无法提供最新答案,但也许有人觉得这种方法更可靠:

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
    })

我对此有何理解:

  1. 当您在选项{ responseType: 'arraybuffer' }中指定时,axios将response.data设置为ArrayBuffer
  2. 接下来,您将创建类似文件的对象-Blob
  3. 您可以通过URL.createObjectURL(blob)的{​​{1}}标签的src属性使用blob文件的网址

如上述article方法中所述,应该更快。

这是jsfiddle demo

UPD:

只需发现您可以在选项img中进行指定,就无需自己创建responseType: 'blob'对象:

Blob

Jsfiddle demo

此处axios issue关于缺少二进制数据操作文档。在此comment中,您可以找到我建议的相同方法。您也可以使用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 }) API,在this stackoverflow注释中,可以找到两种方法的优缺点。