你有在上传文件下载文件踩过坑吗?

简介: 你有在上传文件下载文件踩过坑吗?

上传

上传文件的需求很常见,但还是很容易踩坑,特别是对于之前没用做过类似需求的小伙伴。

  • 首先文件上传请求的参数传递方式通常使用 multipart/form-data 格式。这是一种专门用于在 HTTP 请求中传递二进制文件数据的标准方法。
 fetch('/upload', {
    method: 'POST',
    headers: {
      'Content-Type': 'multipart/form-data',
    },
    body: JSON.stringify(data),
  })
    .then(response => response.json())
    .then(data => {
      console.log('Response from server:', data);
    })
    .catch(error => {
      console.error('Error:', error);
    });
// axios
axios.post(url, formData, {
  headers: {
    'Content-Type': 'multipart/form-data', // 设置请求头
  },
})
  .then(response => {
    console.log('Response from server:', response.data);
    // 处理成功响应
  })
  .catch(error => {
    console.error('Error:', error);
    // 处理错误
  });
  • 获取文件内容,表单提交时和其他字段信息一起上传
  1. 传统的html


<input type="file" id="fileInput">
<button onclick="readFile()">Read File</button>
function readFile() {
  const fileInput = document.getElementById('fileInput');
  const file = fileInput.files[0]; // 获取选择的文件
  if (file) {
    const reader = new FileReader();
    reader.onload = function (event) {
      const fileContent = event.target.result;
      // 在这里处理文件内容
      console.log('File content:', fileContent);
      // 在此可以将文件内容与其他信息一起提交到后端
      // 使用 fetch 或其他 AJAX 方法将数据发送到后端
    };
    reader.readAsText(file); // 使用文本格式读取文件
  } else {
    console.log('No file selected.');
  }
}
  1. 基于ant design 我这里些了多个显示文件的格式。在实际的需求中可以参考使用


import React, { useState } from "react";
import { Input, Tag, Upload } from "antd";
import { DeleteOutlined, FolderOpenOutlined } from "@ant-design/icons";
import _ from "lodash";
import "./style.less";
const UploadCom = () => {
  const [fileList, setFileList] = useState<any>([]);
  const renderList = () => {
    return (
      <div className="tagWrapper">
        {_.map(fileList, (file: any) => {
          return (
            <Tag
              key={file.uid}
              className="tag"
              closable
              onClose={() => {
                setFileList((pre: any) =>
                  _.filter(pre, (p) => p?.uid !== file.uid)
                );
              }}
            >
              <span className="tagText">{file?.name}</span>
            </Tag>
          );
        })}
      </div>
    );
  };
  return (
    <div className="uploadWrapper">
      <div>
        <p>tag形式上传多个文件:</p>
        <Upload
          fileList={[]}
          multiple={true}
          showUploadList={false}
          beforeUpload={(file) => {
            setFileList((pre: any) => [...pre, file]);
            // 如果是在表单里统一提交。这里需要return false
            return false;
          }}
        >
          {/* 文件样式展示多个tag */}
          {renderList()}
        </Upload>
      </div>
      <div style={{ margin: "20px 0" }}>
        <p>上传单个文件输入框类型:</p>
        <Upload
          fileList={[]}
          multiple={true}
          showUploadList={false}
          beforeUpload={(file) => {
            setFileList((pre: any) => [...pre, file]);
            // 如果是在表单里统一提交。这里需要return false
            return false;
          }}
        >
          {/* 单个文件显示文件名 */}
          <Input
            placeholder="请选择文件"
            value={fileList?.[0]?.name}
            prefix={
              <FolderOpenOutlined style={{ color: "rgba(0,0,0,0.65)" }} />
            }
          />
        </Upload>
      </div>
      <div>
        <p>列表形式:</p>
        {_.map(fileList, (file) => {
          return (
            <div className="file-list-item">
              <div> {file.name}</div>
              <DeleteOutlined
                onClick={() => {
                  setFileList((pre: any) =>
                    _.filter(pre, (p) => p?.uid !== file.uid)
                  );
                }}
              />
            </div>
          );
        })}
      </div>
    </div>
  );
};
export default UploadCom;


style:

.uploadWrapper{
  padding: 24px;
  .tagWrapper{
    display: flex;
    align-items: center;
    width: 300px;
    height: 32px;
    border: 1px solid #d9d9d9;
    padding: 0 12px;
    .tag{
      width: 80px;
      display: flex;
      align-items: center;
      .tagText{
        width: 50px;
        display: inline-block;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }
    }
  }
  .file-list-item{
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 300px;
  }
}

下载

  • 下载文件就需要指定响应文件格式responseType为blob二进制文件流,否则很可能打不开文件,说文件内容被损坏。
  • 创建一个 Blob 对象,并将其转换为下载链接
import axios from 'axios';
const url = '/download'; // 下载文件的后端端点
axios.get(url, {
  responseType: 'blob', // 指定响应类型为二进制数据(Blob)
})
  .then(response => {
    const blob = new Blob([response.data], { type: 'text/plain' }); // 文本文档为例
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'filename.ext'; // 设置下载的文件名
    a.style.display = 'none';
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
  })
  .catch(error => {
    console.error('Error:', error);
    // 处理下载失败
  });

其他文件类型

在创建 Blob 对象时,根据文件类型指定 type 参数的值。

  1. JSON 文件
  • application/json:用于表示 JSON 数据。
  • 示例:
const jsonBlob = new Blob([jsonData], { type: 'application/json' });
  1. ZIP 文件
  • application/zip:用于表示 ZIP 压缩文件。
  • 示例:
const zipBlob = new Blob([zipData], { type: 'application/zip' });
  1. Excel 文件
  • 对于旧版的 Excel 文件(.xls):application/vnd.ms-excel
  • 对于新版的 Excel 文件(.xlsx):application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
  • 示例:
const excelBlob = new Blob([excelData], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
  1. Word 文件
  • 对于旧版的 Word 文件(.doc):application/msword
  • 对于新版的 Word 文件(.docx):application/vnd.openxmlformats-officedocument.wordprocessingml.document
  • 示例:
const wordBlob = new Blob([wordData], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });

本文总结的只是个人经验,如有问题,不吝指教。



目录
相关文章
|
存储 Shell
Mac终端工具Terminal (3):在Mac上的终端中执行命令和运行工具
Mac终端工具Terminal (3):在Mac上的终端中执行命令和运行工具
852 0
|
easyexcel Java 测试技术
读取Excel还用POI?试试这款开源工具EasyExcel
读取Excel还用POI?试试这款开源工具EasyExcel
345 0
|
移动开发 资源调度 JavaScript
Vue移动端网页(H5)预览pdf文件(pdfh5和vue-pdf)
这篇文章介绍了在Vue移动端网页中使用`pdfh5`和`vue-pdf`两个插件来实现PDF文件的预览,包括滚动查看、缩放、添加水印、分页加载、跳转指定页数等功能。
8219 1
Vue移动端网页(H5)预览pdf文件(pdfh5和vue-pdf)
|
12月前
|
前端开发 Java 数据安全/隐私保护
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
文章通过一个简单的SpringBoot项目,详细介绍了前后端如何实现用户登录功能,包括前端登录页面的创建、后端登录逻辑的处理、使用session验证用户身份以及获取已登录用户信息的方法。
1549 2
用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程
|
8月前
|
人工智能 算法 调度
DeepSeek杀疯了!国产AI大模型如何重构未来技术版图?
【爆款导读】当ChatGPT还在为每月10亿访问量沾沾自喜时,中国AI军团已悄然完成弯道超车。2025年开年,DeepSeek以雷霆之势横扫中美应用商店双榜,上线72小时突破千万DAU,开发者生态激增300%。通过优化算法降低成本、多模态能力提升效率,DeepSeek不仅在用户数量上取得突破,更在实际应用场景中展现强大实力。其开源策略推动技术民主化,助力更多开发者参与AI开发,成为AI军备竞赛中的佼佼者。
420 20
|
JavaScript 前端开发 算法
【Node.js 版本过高】运行前端时,遇到错误 `Error: error:0308010C:digital envelope routines::unsupported`
【Node.js 版本过高】运行前端时,遇到错误 `Error: error:0308010C:digital envelope routines::unsupported`
8500 0
|
存储 JavaScript API
Vue 3实现的移动端两指控制图片缩放功能
Vue 3实现的移动端两指控制图片缩放功能
1060 0
|
JavaScript 前端开发
vue3 nextTick()应用
在Vue3中,可以使用nextTick函数来延迟执行某些操作,这些操作会在下一次DOM更新周期之后执行。这个函数通常用于在数据更新后,等待DOM更新之后执行一些操作,比如获取DOM元素的尺寸、位置等。
|
存储 敏捷开发 Java
新增16条设计规约!阿里巴巴Java开发手册(详尽版)开放下载!
2018年6月,《阿里巴巴Java开发手册》再次刷新代码规范认知,我们新增了16条设计规约!现免费开放下载,不可错过!
|
机器学习/深度学习 缓存 物联网
AIGC Stable Diffusion文生图Lora模型微调实现虚拟上装
在本教程中,您将学习如何在阿里云交互式建模(PAI-DSW)中,基于Diffusers开源库进行AIGC Stable Diffusion模型的微调训练,以及基于Stable-Diffusion-WebUI开源库启动WebUI进行模型推理。