上传
上传文件的需求很常见,但还是很容易踩坑,特别是对于之前没用做过类似需求的小伙伴。
- 首先文件上传请求的参数传递方式通常使用 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); // 处理错误 });
- 获取文件内容,表单提交时和其他字段信息一起上传
- 传统的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.'); } }
- 基于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
参数的值。
- JSON 文件:
application/json
:用于表示 JSON 数据。- 示例:
const jsonBlob = new Blob([jsonData], { type: 'application/json' });
- ZIP 文件:
application/zip
:用于表示 ZIP 压缩文件。- 示例:
const zipBlob = new Blob([zipData], { type: 'application/zip' });
- 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' });
- 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' });
本文总结的只是个人经验,如有问题,不吝指教。