在 vue.js 中显示原始图像内容类型
Posted
技术标签:
【中文标题】在 vue.js 中显示原始图像内容类型【英文标题】:Display raw image content-type in vue.js 【发布时间】:2018-12-26 22:28:02 【问题描述】:我正在通过带有请求正文的 HTTP GET 从 REST API 检索图像。
我已经设法使用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 的响应。
编辑
关于接受的答案:最后提出的解决方案(UPDATE 2)对我有用(使用 HTTP POST 为请求提供 JSON 正文)。确保使用 axios
(https://github.com/axios/axios) 来执行 HTTP 请求(您可以将其导入 Vue 文件的 <script>
部分,如下所示: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。如果请求方法是 GET 或 HEAD,body 参数被忽略,请求 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 指定正文的方法<img ...>
HTML 标记的src
属性。
@TPPZ 哦,我明白了。您真的需要为 HTTP GET 指定 body 吗?也许它可以与 GET 参数一起使用?
我希望这段 javascript 可以从后端 node.js 移动到浏览器 javascript 部分的某个地方?但是我对浏览器方面的东西不是很熟悉,也许那个缓冲区的东西不能被浏览器处理。目前我需要 GET 请求的主体,因为过去有一系列选择,如果更改将需要大量工作以避免 HTTP 查询参数的 URL 编码问题,我在执行 HTTP 时使用了 HTTP 请求主体GET 请求。以上是关于在 vue.js 中显示原始图像内容类型的主要内容,如果未能解决你的问题,请参考以下文章
TypeError:“原始”参数必须是 Vue.js 应用程序中的函数类型