koa 项目中实现获取本地文件(图片或视频等)并返回给前端显示

14 篇文章 0 订阅
3 篇文章 0 订阅

问题

如何获取 koa 项目中某个目录下的图片文件并返回给前端显示。

具体点来说,就是如何获取下图中 /src/static/img/swiper 目录下的所有图片文件并返回给前端显示呢?

在这里插入图片描述

中途遇到过的坑

一开始直接返回图片在电脑本地的绝对路径,然后前端拿到后进行显示,但是控制台报错了: Not allowed to load local resource,这是由于Chrome浏览器出于安全方面的考虑,所以禁止网页访问本地文件。大意了😂

在这里插入图片描述

解决方法

方法一:

利用 koa-static 插件设置项目的静态资源目录。

1、首先下载 koa-static 插件

npm i koa-static

2、然后全局引入,并设置静态资源目录

const Koa = require('Koa')
const KoaStatic = require('koa-static')

const app = new Koa()

//参数为静态资源的路径
app.use(KoaStatic(path.join(__dirname,'../static')))

3、编写接口逻辑

async getSwiperImg(ctx,next){

    // 读取目录下所有目录文件,返回数组
    let fileArr = fs.readdirSync(path.join(__dirname,'../static/img/swiper'),{encoding:'utf8', withFileTypes:true})
        
    let pathNameArr = []
        
    // 遍历 fileArr ,获取每个图片文件的内容,并存入数组
    fileArr.forEach(item => {
        // 将图片文件路径拼接为 域名+目录(前面设置的静态资源目录)+文件名 的格式
        let filePath = `http://localhost:8000/img/swiper/${item.name}`
        // 存入数组
        pathNameArr.push(file)
    })

    ctx.body = {
        code: 0,
        message: "获取轮播图成功",
        result: pathNameArr
    }
}

通过这种方法前端拿到的图片路径为:

http://localhost:8000/img/swiper_1.jpg

通过这个路径,前端就可以访问到后端的静态目录里对应的静态资源。

方法二:

利用 Data URI scheme 实现前端对图片的访问。

  • 后端: 应该将图片转换成base64的格式,然后再返回给前端。
const fs = require('fs');
const path = require('path');

class indexController{

    async getSwiperImg(ctx,next){
        
        // 读取目录下所有目录文件,返回数组
        let fileArr = fs.readdirSync(path.join(__dirname,'../static/img/swiper'),{encoding:'utf8', withFileTypes:true})
        
        let pathNameArr = []
        
      	// 遍历 fileArr ,获取每个图片文件的内容,并存入数组
        fileArr.forEach(item => {
        
            // 获取每个图片文件的绝对路径
            let filePath = path.join(__dirname,'../static/img/swiper',item.name)
            // 读取图片文件并返回其内容,返回值为 buffer 格式
            let fileObj = fs.readFileSync(filePath);
            // 将 fileObj 从 buffer 转换成 base64 格式
            let file = fileObj.toString('base64');
            
            pathNameArr.push(file)
        })

        ctx.body = {
            code: 0,
            message: "获取轮播图成功",
            result: pathNameArr
        }
    }
}

module.exports = new indexController()
  • 前端: 对图片路径做拼接后即可获取到图片,然后进行展示。

下面代码是在 uniapp 中实现,如直接使用 ajax 或使用 axios 逻辑相同(对返回结果进行路径拼接):

methods: {
	  getSwiper(){
			uni.request({
				url: '/index/swiper',
				method: 'GET',
				success: (res) => {
					let list = []
					// 因为返回来的是个数组,所以对数组进行遍历,给每个元素进行拼接
					res.data.result.forEach(item => {
						let imgUrl = `data:image/png;base64,${item}`
						list.push(imgUrl)
					})
					this.swiperList = list
				}
			})
		}
}

总结

以上两种方法都可以使前端访后端目录下的静态资源,不单止能访问图片文件,其他类型的文件一样可以进行访问(如视频、音频等),上面只是用访问图片文件来进行演示。

👇觉得有帮助的朋友可以支持下作者哦,您的鼓励是我创作的最大动力,如有开发问题可联系作者
请添加图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 服务器端koa2路由代码(假设文件存放在public/files目录下): ``` const Koa = require('koa'); const Router = require('koa-router'); const serve = require('koa-static'); const path = require('path'); const fs = require('fs'); const app = new Koa(); const router = new Router(); // 静态文件服务 app.use(serve(path.join(__dirname, 'public'))); // 获取文件列表路由 router.get('/fileList', async (ctx, next) => { try { const files = fs.readdirSync(path.join(__dirname, 'public', 'files')); const fileList = []; for (let i = 0; i < files.length; i++) { const file = files[i]; const fileInfo = fs.statSync(path.join(__dirname, 'public', 'files', file)); fileList.push({ name: file, size: fileInfo.size, time: fileInfo.mtime }); } ctx.body = fileList; } catch (err) { console.error(err); ctx.status = 500; ctx.body = '服务器错误'; } }); app.use(router.routes()); app.listen(3000); console.log('Server running on http://localhost:3000'); ``` 2. 在前端Vue组件使用axios获取文件列表并渲染缩略图、文件名等信息: ``` <template> <div> <div v-for="file in fileList" :key="file.name"> <img :src="`/files/${file.name}`" width="100" height="100" /> <div>{{ file.name }}</div> <div>{{ getFileSize(file.size) }}</div> <div>{{ formatDate(file.time) }}</div> </div> </div> </template> <script> import axios from 'axios'; export default { data() { return { fileList: [] }; }, mounted() { axios.get('/fileList').then(res => { this.fileList = res.data; }).catch(err => { console.error(err); }); }, methods: { getFileSize(size) { if (size < 1024) { return `${size}B`; } else if (size < 1024 * 1024) { return `${(size / 1024).toFixed(2)}KB`; } else if (size < 1024 * 1024 * 1024) { return `${(size / 1024 / 1024).toFixed(2)}MB`; } else { return `${(size / 1024 / 1024 / 1024).toFixed(2)}GB`; } }, formatDate(time) { const date = new Date(time); return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`; } } }; </script> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值