Отображение необработанного изображения в типе содержимого в vue.js

Я получаю изображение из REST API через HTTP GET с телом запроса.

Мне удалось проверить возвращенный контент с помощью этого теста, используя node.js а также chai.js:

      expect(res).to.have.header('Content-Type', 'image/jpeg');
      expect(res).to.have.header('Access-Control-Allow-Origin', '*');
      expect(res).to.have.header('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers, Origin, X-Requested-With, Content-Type, Accept, Authorization');
      expect(res).to.have.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
      expect(res).to.have.status(200);
      expect(res.body).to.be.instanceof(Buffer); // the image content

в vue.js файл, который я использовал, чтобы прикрепить изображение к <img ...> HTML-тег как это:

<img v-bind:src="urlImg">

Затем, указав в части JavaScript, URL-адрес, как это:

# this string representing the URL is returned by a function
this.urlImg = 'http://example.com/my_img.jpeg' 

но в этом случае я не могу предоставить URL, потому что HTTP GET ожидает, что тело вернет изображение с типом содержимого image/jpeg,

Я даже не уверен, что это возможно, и я могу неправильно понять, как тип контента image/jpeg должен работать. Как мне это сделать в vue.js? Это вообще возможно? Есть ли способ проверить содержимое изображения этого HTTP-ответа, так как с такими вещами, как Postman (приложение Chrome), я не могу проверить ответ, притворяясь рассматривать его как текст /Json.

РЕДАКТИРОВАТЬ

Что касается принятого ответа: последнее предложенное решение (ОБНОВЛЕНИЕ 2) работало для меня (используя HTTP POST, предоставляя тело JSON для запроса). Убедитесь, что вы используете axios ( https://github.com/axios/axios) для выполнения HTTP-запросов (вы можете импортировать его в <script> часть файла Vue, как это: import axios from "axios";).

Я использовал vue-resource ( https://github.com/pagekit/vue-resource) притворяясь, что это было так же, как axios, но это не так, и мне потребовалось время, чтобы понять это.

1 ответ

Решение

Если у вас уже есть Buffer своего изображения вы можете указать предварительно определенную ссылку в вашем клиентском приложении:

this.urlImg = '/my/url/to/get/dynamic/image';

И определите маршрут для отправки изображения с сервера на клиент (для Express):

server.get("my/url/to/get/dynamic/image", function(req, res) {
   var myBuffer = yourFunctionReturnsBuffer();
   res.writeHead(200, {
    'Content-Type': 'image/jpeg',
    'Content-Length': myBuffer.length
   });
   res.end(myBuffer); 
 });

Рабочий пример для запроса Express+: My Gist

ОБНОВИТЬ

Загрузите изображение в браузер через ajax (пример ниже). Но невозможно отправить тело запроса для метода GET с нативным объектом браузера XMLHttpRequest (это основа для всех библиотек ajax). От MDN:

send () принимает необязательный параметр, который позволяет вам указать тело запроса; это прежде всего используется для запроса, такого как PUT. Если метод запроса - GET или HEAD, параметр тела игнорируется, а тело запроса имеет значение null.

var app = new Vue({
    el: "#app",
    data: {
        // empty image
        src: "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
    },
    created() {
        let config = {
            // example url
            url: 'https://www.gravatar.com/avatar/7ad5ab35f81ff2a439baf00829ee6a23',
            method: 'GET',
            responseType: 'blob'
        }
        axios(config)
          .then((response) => {
              let reader = new FileReader();
              reader.readAsDataURL(response.data); 
              reader.onload = () => {
                  this.src = reader.result;
              }
          });
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<div id="app">
  <img :src="src" alt="">
</div>

ОБНОВЛЕНИЕ 2

Декодировать изображение как буфер массива

var app = new Vue({
    el: "#app",
    data: {
        // empty image
        src: "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
    },
    created() {
        let config = {
            // example url
            url: 'https://www.gravatar.com/avatar/7ad5ab35f81ff2a439baf00829ee6a23',
            method: 'GET',
            responseType: 'arraybuffer'
        }
        axios(config)
          .then((response) => {
              var bytes = new Uint8Array(response.data);
              var binary = bytes.reduce((data, b) => data += String.fromCharCode(b), '');
              this.src = "data:image/jpeg;base64," + btoa(binary);
          });
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<div id="app">
  <img :src="src" alt="">
</div>

Другие вопросы по тегам