电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

Python基于React-Dropzone實(shí)現(xiàn)上傳組件的示例代碼

瀏覽:84日期:2022-07-29 08:14:40
目錄實(shí)例演示1. axios上傳普通文件:2. 大文件導(dǎo)入:結(jié)語

這次我要講述的是在React-Flask框架上開發(fā)上傳組件的技巧。我目前主要以React開發(fā)前端,在這個(gè)過程中認(rèn)識(shí)到了許多有趣的前端UI框架——React-Bootstrap、Ant Design、Material UI、Bulma等。而比較流行的上傳組件也不少,而目前用戶比較多的是jQuery-File-Upload和Dropzone,而成長速度快的新晉有Uppy和filepond。比較惋惜的是Fine-Uploader的作者自2018年后就決定不再維護(hù)了,原因作為后來者的我就不多過問了,但請各位尊重每一位開源作者的勞動(dòng)成果。

這里我選擇React-Dropzone,原因如下:

基于React開發(fā),契合度高 網(wǎng)上推薦度高,連Material UI都用他開發(fā)上傳組件 主要以 Drag 和 Drop 為主,但是對于傳輸邏輯可以由開發(fā)者自行設(shè)計(jì)。例如嘗試用socket-io來傳輸file chunks。對于node全棧估計(jì)可行,但是我這里使用的是Flask,需要將Blob轉(zhuǎn)ArrayBuffer。但是如何將其在Python中讀寫,我就沒進(jìn)行下去了。 實(shí)例演示1. axios上傳普通文件:

通過yarn將react-dropzone和引入:

yarn add react-dropzone axios

前端js如下(如有缺失,請自行修改):

import React, { useState, useCallback, useEffect,} from ’react’;import {useDropzone} from ’react-dropzone’;import './dropzone.styles.css'import InfiniteScroll from ’react-infinite-scroller’;import { List, message, // Avatar, Spin,} from ’antd’;import axios from ’axios’;/*** 計(jì)算文件大小* @param {*} bytes * @param {*} decimals * @returns */function formatBytes(bytes, decimals = 2) { if (bytes === 0) return ’0 Bytes’; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = [’Bytes’, ’KB’, ’MB’, ’GB’, ’TB’, ’PB’, ’EB’, ’ZB’, ’YB’]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ’ ’ + sizes[i];}/*** Dropzone 上傳文件* @param {*} props * @returns */function DropzoneUpload(props) { const [files, setFiles] = useState([]) const [loading, setLoading] = useState(false); const [hasMore, setHasMore] = useState(true); const onDrop = useCallback(acceptedFiles => {setLoading(true);const formData = new FormData();smallFiles.forEach(file => { formData.append('files', file);});axios({ method: ’POST’, url: ’/api/files/multiplefiles’, data: formData, headers: {'Content-Type': 'multipart/form-data', }})then(resp => { addFiles(acceptedFiles); setLoading(false);}); }, [files]); // Dropzone setting const { getRootProps, getInputProps } = useDropzone({multiple:true,onDrop, }); // 刪除附件 const removeFile = file => {const newFiles = [...files]newFiles.splice(newFiles.indexOf(file), 1)setFiles(newFiles) } useEffect(() => {// init uploader filessetFiles([]) },[]) return (<section className='container'><div {...getRootProps({className: ’dropzone’})}> <input {...getInputProps()} /> <p>拖動(dòng)文件或點(diǎn)擊選擇文件😊</p></div><div className='demo-infinite-container'> <InfiniteScrollinitialLoad={false}pageStart={0}loadMore={handleInfiniteOnLoad}hasMore={!loading && hasMore}useWindow= {false} ><List dataSource={files} renderItem={item=> (<List.Item actions={[// <a key='list-loadmore-edit'>編輯</a>, <a key='list-loadmore-delete' onClick={removeFile}>刪除</a> ]} // extra={// } key={item.path}> <List.Item.Meta avatar={ <> {!!item.type && [’image/gif’, ’image/jpeg’, ’image/png’].includes(item.type) &&<img width={100} alt=’logo’ src={item.preview}/> } </>}title={item.path}description={formatBytes(item.size)} /></List.Item> )}> {loading && hasMore && (<div className='demo-loading-container'> <Spin /></div> )}</List> </InfiniteScroll></div></section> );}

flask代碼:

def multiplefiles():if ’files’ not in request.files: return jsonify({’message’: ’沒有文件!’}), 200files = request.files.getlist(’files’)for file in files: if file:# 通過拼音解決secure_filename中文問題filename = secure_filename(’’.join(lazy_pinyin(file.filename))Path(UPLOAD_FOLDER + ’/’ + file_info[’dir_path’]).mkdir(parents=True, exist_ok=True)file.save(os.path.join(UPLOAD_FOLDER + ’/’ + file_info[’dir_path’], filename))return jsonify({’message’: ’保存成功!!’})2. 大文件導(dǎo)入:

通過file.slice()方法生成文件的chunks。不要用Promise.all容易產(chǎn)生非順序型的請求,導(dǎo)致文件損壞。

js代碼:

const promiseArray = largeFiles.map(file => new Promise((resolve, reject) => { const chunkSize = CHUNK_SIZE; const chunks = Math.ceil(file.size / chunkSize); let chunk = 0; let chunkArray = new Array(); while (chunk <= chunks) {let offset = chunk * chunkSize;let slice = file.slice(offset, offset+chunkSize)chunkArray.push([slice, offset])++chunk; } const chunkUploadPromises = (slice, offset) => {const largeFileData = new FormData();largeFileData.append(’largeFileData’, slice)return new Promise((resolve, reject) => { axios({method: ’POST’,url: ’/api/files/largefile’,data: largeFileData,headers: { 'Content-Type': 'multipart/form-data'} }) .then(resp => {console.log(resp);resolve(resp); }) .catch(err => {reject(err); })}) }; chunkArray.reduce( (previousPromise, [nextChunk, nextOffset]) => {return previousPromise.then(() => { return chunkUploadPromises(nextChunk, nextOffset);}); }, Promise.resolve()); resolve();}))

flask代碼:

filename = secure_filename(’’.join(lazy_pinyin(filename)))Path(UPLOAD_FOLDER + ’/’ + file_info[’dir_path’]).mkdir(parents=True, exist_ok=True)save_path = os.path.join(UPLOAD_FOLDER + ’/’ + file_info[’dir_path’], filename)# rm file if existsif offset == 0 and save_path.exists(filename): os.remove(filename)try: with open(save_path, ’ab’) as f:f.seek(offset)f.write(file.stream.read())print('time: '+ str(datetime.now())+' offset: ' + str(offset))except OSError: return jsonify({’Could not write to file’}), 500結(jié)語

文件傳輸一直都是HTTP的痛點(diǎn),尤其是大文件傳輸。最好的方式是自己做個(gè)Client,通過FTP和FTPS的協(xié)議進(jìn)行傳輸。第二種來自于大廠很中心化的方法,通過文件的checksum來確定文件是否已經(jīng)上傳了,來營造秒傳的效果。第三種來自去中心化的Bittorrent的方法每一個(gè)用戶做文件種子,提供文件傳輸?shù)妮o助,目前國內(nèi)并沒有普及使用。

到此這篇關(guān)于Python基于React-Dropzone實(shí)現(xiàn)上傳組件的示例代碼的文章就介紹到這了,更多相關(guān)Python React-Dropzone上傳組件內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Python 編程
相關(guān)文章:
主站蜘蛛池模板: 真空搅拌机-行星搅拌机-双行星动力混合机-广州市番禺区源创化工设备厂 | 净化工程_无尘车间_无尘车间装修-广州科凌净化工程有限公司 | 北钻固控设备|石油钻采设备-石油固控设备厂家 | 长沙中央空调维修,中央空调清洗维保,空气能热水工程,价格,公司就找维小保-湖南维小保环保科技有限公司 | 威实软件_软件定制开发_OA_OA办公系统_OA系统_办公自动化软件 | 天坛家具官网| 云南外加剂,云南速凝剂,云南外加剂代加工-普洱澜湄新材料科技有限公司 | 股票入门基础知识_股票知识_股票投资大师_格雷厄姆网 | 不锈钢复合板厂家_钛钢复合板批发_铜铝复合板供应-威海泓方金属复合材料股份有限公司 | 电杆荷载挠度测试仪-电杆荷载位移-管桩测试仪-北京绿野创能机电设备有限公司 | 扫地车厂家-山西洗地机-太原电动扫地车「大同朔州吕梁晋中忻州长治晋城洗地机」山西锦力环保科技有限公司 | 挤塑板-XPS挤塑板-挤塑板设备厂家[襄阳欧格] | 水成膜泡沫灭火剂_氟蛋白泡沫液_河南新乡骏华消防科技厂家 | 上海刑事律师|刑事辩护律师|专业刑事犯罪辩护律师免费咨询-[尤辰荣]金牌上海刑事律师团队 | 拉力机-万能试验机-材料拉伸试验机-电子拉力机-拉力试验机厂家-冲击试验机-苏州皖仪实验仪器有限公司 | 郑州水质检测中心_井水检测_河南废气检测_河南中环嘉创检测 | 打包钢带,铁皮打包带,烤蓝打包带-高密市金和金属制品厂 | 中医中药治疗血小板减少-石家庄血液病肿瘤门诊部 | 四川成都干燥设备_回转筒干燥机_脉冲除尘器_输送设备_热风炉_成都川工星科机电设备有限公司 | 膜结构车棚|上海膜结构车棚|上海车棚厂家|上海膜结构公司 | 诗词大全-古诗名句 - 古诗词赏析 | 石家庄网站建设|石家庄网站制作|石家庄小程序开发|石家庄微信开发|网站建设公司|网站制作公司|微信小程序开发|手机APP开发|软件开发 | 振动传感器,检波器-威海广达勘探仪器有限公司 | 建筑工程资质合作-工程资质加盟分公司-建筑资质加盟 | 无纺布包装机|径向缠绕包装机|缠绕膜打包机-上海晏陵智能设备有限公司 | 青岛侦探_青岛侦探事务所_青岛劝退小三_青岛婚外情取证-青岛王军侦探事务所 | 密封圈_泛塞封_格莱圈-[东莞市国昊密封圈科技有限公司]专注密封圈定制生产厂家 | LED显示屏_LED屏方案设计精准报价专业安装丨四川诺显科技 | 法钢特种钢材(上海)有限公司 - 耐磨钢板、高强度钢板销售加工 阀门智能定位器_电液动执行器_气动执行机构-赫尔法流体技术(北京)有限公司 | 120kv/2mA直流高压发生器-60kv/2mA-30kva/50kv工频耐压试验装置-旭明电工 | 飞扬动力官网-广告公司管理软件,广告公司管理系统,喷绘写真条幅制作管理软件,广告公司ERP系统 | 石牌坊价格石牌坊雕刻制作_石雕牌坊牌楼石栏杆厂家_山东嘉祥石雕有限公司 | 防腐木批发价格_深圳_惠州_东莞防腐木厂家_森源(深圳)防腐木有限公司 | 钢木实验台-全钢实验台-化验室通风柜-实验室装修厂家-杭州博扬实验设备 | 南京展台搭建-南京展会设计-南京展览设计公司-南京展厅展示设计-南京汇雅展览工程有限公司 | 钢丝绳探伤仪-钢丝绳检测仪-钢丝绳探伤设备-洛阳泰斯特探伤技术有限公司 | 撕碎机,撕破机,双轴破碎机-大件垃圾破碎机厂家 | 杭州高温泵_热水泵_高温油泵|昆山奥兰克泵业制造有限公司 | 物流公司电话|附近物流公司电话上门取货 | 档案密集架,移动密集架,手摇式密集架,吉林档案密集架-厂家直销★价格公道★质量保证 | 湖南档案密集架,智能,物证,移动,价格-湖南档案密集架厂家 |