Vuejs 没有完全从后端加载图像 API
Vuejs not loading image completely from backend API
上下文:
我有一个 WebApp(前端:Vue3,后端:node.js + express),带有一个 vue 和一个按钮。单击按钮时,它会在后端触发脚本,下载图像并将其存储在本地。此图像应在 Vue 端呈现。
我的问题:
一切似乎都正常,只是 Vue 没有完全显示图像。我只显示了一小部分文件。
后端控制器(images.controller.js
):
const fs = require('fs');
const path = require('path');
const axios = require('axios');
const { v4: uuidv4 } = require('uuid');
const downloadImage = async(fileUrl, fileName) => {
let isDownloaded = false
const downloadFolder = './images';
const localFilePath = path.resolve(__dirname, downloadFolder, fileName);
try {
const response = await axios({
method: 'GET',
url: fileUrl,
responseType: 'stream',
});
if(response.status === 200){
isDownloaded = true;
await response.data.pipe(fs.createWriteStream(localFilePath));
}
} catch (error) {
console.log(error)
}
return isDownloaded;
}
const readImage = async(req, res) => {
try {
const fileName = `${uuidv4()}.jpeg`;
const fileUrl = 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/dog-puppy-on-garden-royalty-free-image-1586966191.jpg';
const isDownloaded = await downloadImage(fileUrl, fileName);
if(isDownloaded){
const img = fs.readFile(__dirname + '/images/' + fileName, async(err, data) => {
var contenType = 'image/jpeg';
var base64 = await Buffer.from(data).toString('base64');
base64 = 'data:image/jpeg;base64,' + base64;
res.status(200).send(base64)
})
}
} catch (error) {
console.log(error)
}
}
module.exports = {
readImage: readImage,
}
前端,我的Home.vue
:
<template>
<div class="home">
<button @click="readImage">TEST</button>
<div v-if="img">
<img :src="img">
</div>
</div>
</template>
<script>
import ImagesService from '../services/images.service'
export default {
name: 'Home',
data(){
return {
img: ''
}
},
methods: {
async readImage(){
const temp = await ImagesService.readImages({name: 'dog.jpeg'})
this.img = temp.data
}
},
}
</script>
images.service.js
:
import api from '../../http-common';
export default new class ImagesService {
//Read Screenshot
readImages(imageName){
return api.post('read/image', imageName)
}
}
http-common.js:
import axios from 'axios'
export default axios.create({
baseURL: 'http://localhost:3003/api',
headers: {
"Content-type": "application/json",
}
})
这是因为流不是一个承诺:图像在流完成保存之前被读取和下载
尝试将 data.pipe
包装在一个 promise 中,并在保存完成后解决:
const downloadImage = (fileUrl, fileName) => {
return new Promise(async(resolve, reject) => {
let isDownloaded = false
const downloadFolder = './images';
const localFilePath = path.resolve(__dirname, downloadFolder, fileName);
const imgStream = fs.createWriteStream(localFilePath);
try {
const response = await axios({
method: 'GET',
url: fileUrl,
responseType: 'stream',
});
if (response.status === 200) {
response.data.pipe(imgStream);
}
} catch (error) {
console.log(error)
reject(error);
}
imgStream.on('finish', () => {
resolve(true);
});
})
};
上下文: 我有一个 WebApp(前端:Vue3,后端:node.js + express),带有一个 vue 和一个按钮。单击按钮时,它会在后端触发脚本,下载图像并将其存储在本地。此图像应在 Vue 端呈现。
我的问题: 一切似乎都正常,只是 Vue 没有完全显示图像。我只显示了一小部分文件。
后端控制器(images.controller.js
):
const fs = require('fs');
const path = require('path');
const axios = require('axios');
const { v4: uuidv4 } = require('uuid');
const downloadImage = async(fileUrl, fileName) => {
let isDownloaded = false
const downloadFolder = './images';
const localFilePath = path.resolve(__dirname, downloadFolder, fileName);
try {
const response = await axios({
method: 'GET',
url: fileUrl,
responseType: 'stream',
});
if(response.status === 200){
isDownloaded = true;
await response.data.pipe(fs.createWriteStream(localFilePath));
}
} catch (error) {
console.log(error)
}
return isDownloaded;
}
const readImage = async(req, res) => {
try {
const fileName = `${uuidv4()}.jpeg`;
const fileUrl = 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/dog-puppy-on-garden-royalty-free-image-1586966191.jpg';
const isDownloaded = await downloadImage(fileUrl, fileName);
if(isDownloaded){
const img = fs.readFile(__dirname + '/images/' + fileName, async(err, data) => {
var contenType = 'image/jpeg';
var base64 = await Buffer.from(data).toString('base64');
base64 = 'data:image/jpeg;base64,' + base64;
res.status(200).send(base64)
})
}
} catch (error) {
console.log(error)
}
}
module.exports = {
readImage: readImage,
}
前端,我的Home.vue
:
<template>
<div class="home">
<button @click="readImage">TEST</button>
<div v-if="img">
<img :src="img">
</div>
</div>
</template>
<script>
import ImagesService from '../services/images.service'
export default {
name: 'Home',
data(){
return {
img: ''
}
},
methods: {
async readImage(){
const temp = await ImagesService.readImages({name: 'dog.jpeg'})
this.img = temp.data
}
},
}
</script>
images.service.js
:
import api from '../../http-common';
export default new class ImagesService {
//Read Screenshot
readImages(imageName){
return api.post('read/image', imageName)
}
}
http-common.js:
import axios from 'axios'
export default axios.create({
baseURL: 'http://localhost:3003/api',
headers: {
"Content-type": "application/json",
}
})
这是因为流不是一个承诺:图像在流完成保存之前被读取和下载
尝试将 data.pipe
包装在一个 promise 中,并在保存完成后解决:
const downloadImage = (fileUrl, fileName) => {
return new Promise(async(resolve, reject) => {
let isDownloaded = false
const downloadFolder = './images';
const localFilePath = path.resolve(__dirname, downloadFolder, fileName);
const imgStream = fs.createWriteStream(localFilePath);
try {
const response = await axios({
method: 'GET',
url: fileUrl,
responseType: 'stream',
});
if (response.status === 200) {
response.data.pipe(imgStream);
}
} catch (error) {
console.log(error)
reject(error);
}
imgStream.on('finish', () => {
resolve(true);
});
})
};