react 中使用 plupload 上传文件

本文介绍了在React应用中使用plupload插件上传文件遇到的问题及其解决方案。首先,由于初始化时机不当导致选择文件对话框无法弹出,将uploader实例创建和初始化移到componentDidMount中解决。接着,当文件上传失败后,再次点击上传按钮无法触发上传,原因是plupload的上传队列机制。通过查阅文档发现addFile方法可以手动添加文件到队列,结合uploader.files数组中的File实例,使用getNative()方法获取native file对象,从而解决二次上传问题。
摘要由CSDN通过智能技术生成

这几天做一个项目的迭代开发,需要在react 中使用plupload 插件实现上传文件。需求很简单,如下图,点击“...” 按钮选择文件,点击“Import”按钮上传文件。


 plupload 上传文件大概分为以下几步:

1. 新建一个uploader实例,并在构造时配置好上传的相关属性。

const uploader = new plupload.Uploader({
     browse_button: 'selectFileId', //指定调起选择文件对话框的DOM 元素或其ID,注意是DOM元素
     url: ‘put upload file url here’,
     multi_selection: false,
   init: { //在里面定义各种事件的回调
        BeforeUpload: (uploader,file) => {
          
        },
        FilesAdded:(uploader,files)=>{
          
        },
        FileUploaded:(uploader,file,info) =>{
          
        }, 
   }
})

2. 初始化实例

this.uploader.init();

3. 在确定导入的按钮相关触发事件(例如onclick)的回调中调用实例的start方法,开始上传

handleImport = () => {
    this.uploader.start();
}

但是在调试过程中问题一就出现了。

问题一:发现点击“...” 按钮无法调起选择文件对话框。跟踪发现init()函数也有被调用,说明uploader初始化没成功。反复检查配置,没发现配置有任何问题。既然配置没问题,那就可能是初始化的时机不对。检查发现,uploader的实例创建和init初始化都放在了 react component的 componentWillMount() 函数中。 突然醒悟,componentWillMount 是在react 创建的组件插入DOM节点之前触发的,也就是说调用时DOM中还没有ID为selectFlagId的元素,uploader 初始化时当然是找不到触发DOM的。谜底解开。。。

问题一解决后,接着测试,又发现了问题二。

问题二:当第一次触发上传,服务端检查发现文件内容不符合规范,返回错误。这个时候,用户直接打开文件修改保存,再在界面直接点击上传按钮,发现无法上传文件,但是重新选择文件后,又可以上传。打开chrome 开发工具,检查网络请求,发现无上传请求发出。然后设断点跟踪,发现handleImport() 函数是调用了的,uploader 的start 函数也是调用了的,但是BeforeUpload函数没有进入。也就是说是uploader 在接受到start信号后,没有触发上传。此刻小编脑上各种⭕️, 到这里,就需要去了解pluploader内部的上传机制了。打开plupload 官方文档查阅,发现在plupload内部有一个上传队列,每次选择文件后,都会把文件放入队列中,每次start时,都会从队列中拿任务。但是由于第一上传已经触发,任务已经执行;第二次点击时,任务队列其实是空的,拿不到任务,自然不会上传;如果再次选择文件,文件又会被放入队列,因此可以拿到任务,进行上传。谜底揭晓了。

那问题来了,怎么解决呢?

首次需求是要满足的,不能要求用户一定要再选一次文件吧,毕竟用户是我们的衣食父母啊; 

其次࿰

要在React打包和上传图片文件,可以使用以下步骤: 1. 在React项目安装依赖:`npm install axios react-dropzone` 2. 创建一个组件来选择和上传图片: ```jsx import React, { useState } from "react"; import axios from "axios"; import Dropzone from "react-dropzone"; const ImageUploader = () => { const [selectedFile, setSelectedFile] = useState(null); const handleFileSelect = (files) => { setSelectedFile(files[0]); }; const handleUpload = async () => { const formData = new FormData(); formData.append("file", selectedFile); const response = await axios.post("/api/upload", formData, { headers: { "Content-Type": "multipart/form-data", }, }); console.log(response.data); }; return ( <div> <Dropzone onDrop={handleFileSelect}> {({ getRootProps, getInputProps }) => ( <div {...getRootProps()}> <input {...getInputProps()} /> {selectedFile ? ( <div> <p>Selected file: {selectedFile.name}</p> <button onClick={handleUpload}>Upload</button> </div> ) : ( <p>Drag and drop a file here, or click to select a file</p> )} </div> )} </Dropzone> </div> ); }; export default ImageUploader; ``` 3. 在后端创建一个API来接收上传的文件: ```js const express = require("express"); const multer = require("multer"); const path = require("path"); const app = express(); const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, "uploads/"); }, filename: function (req, file, cb) { cb(null, file.fieldname + "-" + Date.now() + path.extname(file.originalname)); }, }); const upload = multer({ storage: storage }); app.post("/api/upload", upload.single("file"), (req, res) => { console.log(req.file); res.send("File uploaded successfully"); }); app.listen(5000, () => { console.log("Server started on port 5000"); }); ``` 在这个示例,我们使用`multer`间件来处理上传的文件,并将其保存到`uploads/`目录。我们还将文件重命名为`fieldname-timestamp.extname`的格式。 4. 在`App.js`使用这个组件: ```jsx import React from "react"; import ImageUploader from "./ImageUploader"; const App = () => { return ( <div> <h1>Image Uploader</h1> <ImageUploader /> </div> ); }; export default App; ``` 这样,你就可以选择一个图片文件并将其上传到服务器了。请注意,你需要在服务器上创建一个`uploads/`目录来保存上传的文件。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值