在 vue.js 中显示原始图像内容类型

Posted

技术标签:

【中文标题】在 vue.js 中显示原始图像内容类型【英文标题】:Display raw image content-type in vue.js 【发布时间】:2018-12-26 22:28:02 【问题描述】:

我正在通过带有请求正文的 HTTP GET 从 REST API 检索图像。

我已经设法使用node.jschai.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 的响应。

编辑

关于接受的答案:最后提出的解决方案(UPDATE 2)对我有用(使用 HTTP POST 为请求提供 JSON 正文)。确保使用 axios (https://github.com/axios/axios) 来执行 HTTP 请求(您可以将其导入 Vue 文件的 &lt;script&gt; 部分,如下所示:import axios from "axios";)。

我使用vue-resource (https://github.com/pagekit/vue-resource) 假装它与axios 相同,但事实并非如此,我花了一段时间才意识到这一点。

【问题讨论】:

我没有看到任何正确的问题,您的 url 可以返回除图像之外的其他内容,或者您​​将图像下载为缓冲区并且您想要显示它还是什么? 我正在尝试显示从后端下载为缓冲区的图像,它将其返回为content-type=image/jpeg,谢谢 【参考方案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+request 的工作示例:My Gist

更新

通过 ajax 在浏览器中加载图像(示例如下)。但是无法使用本机浏览器 XMLHttpRequest 对象发送 GET 方法的请求正文(这是所有 ajax 库的基础)。来自 MDN:

send() 接受一个可选参数,让您指定请求的正文;这主要用于请求,例如 PUT。如果请求方法是 GETHEADbody 参数被忽略,请求 body 设置为 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" >
</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" >
</div>

【讨论】:

有没有办法避免后端/快递部分?就像在浏览器中以某种方式运行该javascript?我当前的设置是一个非常薄的 Vue.js 应用程序,使用 webpack 打包,没有这样的 node.js 后端。我试图让浏览器部分仅包含 HTML 模板、CSS 和遵循“3 块 HTML/CSS/Js 模式”的最少 javascript 代码,用于以“.vue”结尾的文件谢谢! @TPPZ 但是如果你没有后端你如何下载文件?为什么你不能直接在你的 Vue 应用程序中指定图片 url(更好地解释这部分)? 要获取该图像,我正在执行一个 HTTP GET 请求,提供一个请求正文(类似于 HTTP POST),但是我找不到为 URL 中的 HTTP GET 指定正文的方法&lt;img ...&gt; HTML 标记的src 属性。 @TPPZ 哦,我明白了。您真的需要为 HTTP GET 指定 body 吗?也许它可以与 GET 参数一起使用? 我希望这段 javascript 可以从后端 node.js 移动到浏览器 javascript 部分的某个地方?但是我对浏览器方面的东西不是很熟悉,也许那个缓冲区的东西不能被浏览器处理。目前我需要 GET 请求的主体,因为过去有一系列选择,如果更改将需要大量工作以避免 HTTP 查询参数的 URL 编码问题,我在执行 HTTP 时使用了 HTTP 请求主体GET 请求。

以上是关于在 vue.js 中显示原始图像内容类型的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:“原始”参数必须是 Vue.js 应用程序中的函数类型

如何更改php中的内容类型?

使用 vue.js 在图像上传时保存图像类型

尝试在vue js中上传图像时未捕获类型错误非法调用?

从 multipart/alternative 获取原始内容类型

.NET 图像处理程序在下载时剥离文件类型