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

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

上传

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

  • 首先文件上传请求的参数传递方式通常使用 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' });

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



目录
相关文章
|
10月前
|
前端开发
前端:下载文件(多种方法)
前端:下载文件(多种方法)
784 0
|
11月前
|
XML 存储 移动开发
前端文件下载的正确打开方式
前端涉及到的文件下载还是很多应用场景的,那么前端文件下载有多少种方式呢?每种方式有什么优缺点呢?下面就来一一介绍。
112 0
|
前端开发
前端上传文件或者上传文件夹
前端上传文件或者上传文件夹
176 0
前端上传文件或者上传文件夹
|
前端开发
前端下载文件的几种方式
前端下载文件的几种方式
1081 0
下载文件
下载文件
89 0
|
缓存 Java
sevlet实现下载文件功能
希望做一个小板块,实现文件的上传和下载,那么上传实现了,就需要实现下载,阅读了各位的博客总结了一下。在网页中通过超链接是可以访问我的资源的,浏览器不可访问的资源他就会下载到本地,像一些浏览器可以直接访问的如图片,txt文件浏览器会直接打开。这就需要我们在sevlet中统一处理文件下载。
109 0
sevlet实现下载文件功能
|
前端开发 JavaScript API
我学会了,写一个前端下载文件功能
过去有很多次文件下载的功能,但是都没有记录下来,这次有空就把文件下载的功能从0写一遍,于是就有了这篇文章。 我会从简到难的方式去实现下载功能。从直接下载字符串到简单请求下载文件,最终通过后端返回的文件名来实现动态下载文件。
600 0
我学会了,写一个前端下载文件功能
|
存储 Linux Python
Linux命令行上传文件到百度网盘
最近在学习 MySQL 的 bin-log 时候考虑到数据备份的问题,突然想到如果能将数据通过 Linux 命令行方式备份到百度网盘,那是一件多么牛逼的事情。百度网盘有免费的 2TB 存储空间,而且有百度做靠山,不怕数据丢失,安全可靠。
3030 0
|
分布式计算 Hadoop 开发者
文件下载| 学习笔记
快速学习文件下载
190 0
|
开发者
Jeesite4本地及服务器上传文件、图片详解
Jeesite4本地及服务器上传文件、图片详解
630 0