面试官:如何实现文件上传?说说你的思路

面试官:如何实现文件上传?说说你的思路

在这里插入图片描述

一、什么是文件上传?

文件上传在日常开发中应用很广泛,比如在发微博、发微信朋友圈等操作中都会用到图片上传功能。由于浏览器的安全限制,浏览器不能直接操作文件系统,因此需要通过浏览器暴露出来的统一接口来访问文件,然后将文件内容读取到指定的内存中,并执行提交请求操作,将内存中的文件内容上传到服务端,服务端再解析前端传来的数据信息,最终将文件保存到服务器的文件系统中。

文件上传需要设置请求头为content-type: multipart/form-data,其中multipart表示互联网上的混合资源,即资源由多种元素组成,而form-data表示可以使用HTML Forms和POST方法上传文件。

文件上传的请求结构如下:

POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data; boundary=--------------------------1234567890

--------------------------1234567890
Content-Disposition: form-data; name="file"; filename="example.jpg"
Content-Type: image/jpeg

... binary data of the image ...
--------------------------1234567890--

其中,boundary表示分隔符,用于分隔不同的表单项。每个表单项必须包含Content-Disposition头,其他头信息如Content-Type为可选项。

二、如何实现文件上传?

文件上传可以分为两个步骤:

  1. 文件的上传
  2. 文件的解析

1. 文件上传

在前端,我们可以通过HTML的<input type="file">元素来实现文件上传的表单:

<form action="http://localhost:8080/api/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file" id="file" value="" multiple="multiple" />
    <input type="submit" value="提交"/>
</form>

在后端,我们可以使用Koa框架中的koa-body中间件来解析上传的文件数据:

npm install koa-body
const Koa = require('koa');
const koaBody = require('koa-body');
const app = new Koa();

app.use(koaBody({
    multipart: true,
    formidable: {
        maxFileSize: 200 * 1024 * 1024    // 设置上传文件大小最大限制,默认2M
    }
}));

app.use(async (ctx) => {
    // 获取上传的文件
    const file = ctx.request.files.file;
    // 创建可读流
    const reader = fs.createReadStream(file.path);
    let filePath = path.join(__dirname, 'public/upload/') + `/${file.name}`;
    // 创建可写流
    const upStream = fs.createWriteStream(filePath);
    // 可读流通过管道写入可写流
    reader.pipe(upStream);
    ctx.body = "上传成功!";
});

app.listen(8080, () => {
    console.log('Server started on http://localhost:8080');
});

2. 文件解析

在服务器端,我们需要将上传的文件进行解析,保存到指定的目录中。在上述代码中,我们通过使用fs模块来处理文件的保存操作。

除了使用koa-body,我们还可以使用koa-multer中间件来实现文件上传:

npm install koa-multer
const Koa = require('koa');
const Router = require('koa-router');
const multer = require('koa-multer');
const path = require('path');

const app = new Koa();
const router = new Router();

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "./upload/")
  },
  filename: (req, file, cb) => {
    cb(null, Date.now() + path.extname(file.originalname))
  }
})

const upload = multer({
  storage
});

router.post("/upload", upload.single('file'), (ctx, next) => {
  console.log(ctx.req.file); // 获取上传文件
})

app.use(router.routes());

app.listen(8080, () => {
    console.log('Server started on http://localhost:8080');
});

以上代码中,我们使用multer中间件来实现文件上传,storage选项用于设置文件的保存路径和文件名,upload.single('file')表示只上传单个文件。

参考文献

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linwu-hi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值