分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 前端开发

fetch 实现文件上传

发布时间:2023-09-06 01:43责任编辑:蔡小小关键词:文件上传

摘要

这次实现补了好几个以前遗漏的点

form 表单 type=file 的 input 提交的file是固定类型的对象

包括 file 多个属性

手动如何拼接 form data

拼接的时候尝试用 file reader 获取到的二进制手动创造 File 对象,失败... 对比发现和前台获取的file 对象缺失很多属性,比如name、lastModified 、type 等等。尝试用 blob 对象(file 的基类)与后端交互也失败,可能某些能解析二进制文件内容的后端框架可以实现直接传文件内容就实现交互,我们现在用的是webx 比较古老的框架。
拼接的form data 如下

multipart/form-data主要由三部分组成:

HTTP Header。需要添加头"Content-Type: multipart/form-data; boundary=%s",这个boundary就是分隔符,见第二条。
分隔符boundary。分隔符是一串和正文内容不冲突的字符串,用以分割多个参数。一般都是N个减号+随机字符串,比如"----------当前时间"。
正文需要加header:
Content-Disposition: form-data; name="%s",%s为需要传递的变量名。
Content-Type: 指定正文MIME类型,默认是纯文本text/plain,未知类型可以填application/octet-stream。
数据。要注意的是数据的编码,文档上说"7BIT encoding",ISO-8859-1即可

备注: File 对象解释 https://developer.mozilla.org/en-US/docs/Web/API/File

提交的请求 content type

不要手动设置, 我当初手动设置 multi-part/data , 但是少了浏览器自动生成的boundary参数,缺失也无法解析。

下面是几个常见的Content-Type:

1.text/html
2.text/plain
3.text/css
4.text/javascript
5.application/x-www-form-urlencoded
6.multipart/form-data
7.application/json
8.application/xml

具体项目结构及代码实现

前台

<input type="file" onChange={this.uploadSuccess} accept=".xlsx" id="uploadFile"/><input type="file" onChange={this.uploadSuccess} accept=".xlsx" id="uploadFile"/>uploadSuccess = (e) => { ?const { changeUploadFile } = this.props; ?const _this = this; ?var reader = new FileReader(); ?reader.onload = function (readerEvent) { ???// 存储上传的文件 ???changeUploadFile(readerEvent.target.result); ?// !! 这里可以获取到文件的二进制内容 ???_this.props.searchBatchUploadEntity(document.getElementById('uploadFile').files[0]); ?}; ?reader.readAsText(e.target.files[0]);}

shared worker 侧

function wrapFormData(options) { ?const formData = new FormData(); ?for (var key of Object.keys(options)) { ???let value = options[key]; ???formData.append(key, value); ?} ?return formData;}function fetchApi(url,init){ ?init = init || {}; ?init.headers = init.headers || {}; ?init.credentials = 'include'; //for pass cookie ?if(init.body){ ???init.method = init.method || 'POST'; ?} ?init.headers['X-Proxy-Timeout'] = init.timeout || defalutTimeout; ?var bodyJson = false; ?if(Object.prototype.toString.call(init.body) === '[object Object]'){ ???bodyJson = true; ???init.body = JSON.stringify(init.body); ?} ?console.time('[performance]_network',url) ?return fetch(url,init).then((res) => { ???console.timeEnd('[performance]_network',url) ???if(res.status === 304) { ?????return 304; ???} ???if(bodyJson){ ?????init.body = JSON.parse(init.body); ???} ???if(!res.ok){ ?????throw new Error(`${res.status} ${res.statusText}`); ???} ???console.time('[performance]_parse',url) ???let resu = res.json(); ???console.timeEnd('[performance]_parse',url) ???return resu; ?},(err) => { ???throw err; ?});}function fetchSuccess (url,init) { ?console.time('[performance]_'+url) ?return fetchApi(url,init).then((data) => { ???console.timeEnd('[performance]_'+url) ???if(data === 304) { ?????return 304; ???} ???if(data.returnCode){ ?????throw new Error(data.returnMessage || JSON.stringify(data)); ???} ???return data.returnValue; ?},(err) => { ???throw err; ?});}const init = { ?method: 'post', ?body: wrapFormData({ ???graphName, ???file, ?}), ?Accept: 'application/json, application/xml, text/plain, text/html, *.*',}fetchSuccess(ROUTER.SEARCH_BATCH_UPLOAD_ENTITY, init).then((result) => { ?cb(null, result);}, (err) => { ?cb(err);});

fetch 实现文件上传

原文地址:https://www.cnblogs.com/huxiaoyun90/p/8475989.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved