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

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

上传

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

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

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



目录
相关文章
|
7月前
|
机器学习/深度学习 JSON 前端开发
一篇文章讲明白dropzone上传文件
一篇文章讲明白dropzone上传文件
118 0
|
前端开发
前端:下载文件(多种方法)
前端:下载文件(多种方法)
899 0
|
前端开发
前端上传文件或者上传文件夹
前端上传文件或者上传文件夹
265 0
前端上传文件或者上传文件夹
|
前端开发 Java Apache
文件上传与下载
文件上传与下载 文件上传也称为upload,是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程。文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能。 文件上传时,对页面的form表单有如下要求: method=“post” 采用post方式提交数据 enctype=“multipart/form-data” 采用multipart格式上传文件 type=“file” 使用input的file控件上传
|
开发者
上传文件到服务器 | 学习笔记
快速学习上传文件到服务器。
139 0
上传文件到服务器 | 学习笔记
|
Java 开发者
单文件上传 | 学习笔记
快速学习单文件上传,介绍了单文件上传系统机制, 以及在实际应用过程中如何使用。
单文件上传 | 学习笔记
|
缓存 Java
sevlet实现下载文件功能
希望做一个小板块,实现文件的上传和下载,那么上传实现了,就需要实现下载,阅读了各位的博客总结了一下。在网页中通过超链接是可以访问我的资源的,浏览器不可访问的资源他就会下载到本地,像一些浏览器可以直接访问的如图片,txt文件浏览器会直接打开。这就需要我们在sevlet中统一处理文件下载。
150 0
sevlet实现下载文件功能
|
前端开发 JavaScript API
我学会了,写一个前端下载文件功能
过去有很多次文件下载的功能,但是都没有记录下来,这次有空就把文件下载的功能从0写一遍,于是就有了这篇文章。 我会从简到难的方式去实现下载功能。从直接下载字符串到简单请求下载文件,最终通过后端返回的文件名来实现动态下载文件。
725 0
我学会了,写一个前端下载文件功能
下载文件
下载文件
112 0
|
缓存 安全 JavaScript
如何实现上传文件到 nodejs 和文件下载
最近拿 next.js 做个全栈项目,需要文件上传和下载,这里记录下实现方式,也写一下使用原生 node 代码如何实现。

热门文章

最新文章