在小程序中使用formdata上传数据,可实现多文件上传

发布于:2024-04-05 ⋅ 阅读:(28) ⋅ 点赞:(0)

1.下载formdata

GitHub - zlyboy/wx-formdata: 在小程序中使用formdata上传数据,可实现多文件上传

2. 前端页面

<uni-collapse class='collapse' ref='collapse'>
                <uni-collapse-item v-for="(item, index) in attachmentList"
                :key="index"
                :title="item.dictName" class='collapse-item' title-border='show' :border='false'>
                    <view class="content">
                    <FileUploader  :attachment="item" :uniqueId='uniqueId' @handleHeight='handleHeight' v-model="item.attachmentIds" />
                    </view>
                </uni-collapse-item>
            </uni-collapse>
attachmentList: [
            {
            "id": 1,
            "dictCode": "XCDCTP",
            "dictName": "现场调查图片",
            "categoryCode": ",XCDCTP,",
            "servicePhase": "sb",
            "attachmentIds":[]
            },
        ],
        isFetching: false,
        uniqueId:'',

3.组件

<template>

	<view>
		<view class="file_list">
			<view class="file_list__box" v-for="(file,index) in fileList" :key="index" @click="fileActive(file)">
				<uni-icons type="paperclip" size="15"></uni-icons>
				<text>{{file.name}}</text>
				<view class="delete_file" @click.stop="deleteFile(index,file)">
					<uni-icons type="clear" size="16"></uni-icons>
				</view>
			</view>
		</view>
		<view class="uni-file-picker__container">
			<view class="file-picker__box" v-for="(image,index) in imageList" :key="index">
				<view class="file-picker__box-content">
					<image class="file-image" :src="image.url" mode="aspectFill" :data-src="image.url"
						@click.stop="previewImage">
					</image>
					<view class="icon-del-box" @click.stop="deleteImage(index,image)">
						<view class="icon-del"></view>
						<view class="icon-del rotate"></view>
					</view>
				</view>
			</view>
			<view class="file-picker__box" v-for="(video,index) in videoList" :key="index">
				<view class="file-picker__box-content">
					<video class="file-image" :src="video.url"></video>
					<view class="icon-del-box" @click.stop="deleteVideo(index,video)">
						<view class="icon-del"></view>
						<view class="icon-del rotate"></view>
					</view>
				</view>
			</view>
			<view v-if="VideoOfImagesShow" class="file-picker__box">
				<view class="file-picker__box-content is-add" @tap="chooseVideoImage">
					<slot>
						<view class="icon-add"></view>
						<view class="icon-add rotate"></view>
					</slot>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import {
		uploadFile,saveAttachInfo,deleteAttachment,uploadFileByName
	} from '@/service/api.js'
	import {
		showToast
	} from '@/utils/index.js'
	import {
		BASE_API_URL
	} from '@/common/config.js'
	import {
		appStorage
	} from '@/utils/storage.js'
	const FormData = require('@/utils/formdata/index.js')
	
	export default {
		props: {
			attachment: Object,
			uniqueId:String
		},
		data() {
			return {
				imageList: [], //图片
				videoList: [], //视频存放
				fileList: [], //文件
				ids: [],
				sourceTypeIndex: 2,
				sourceType: ['拍摄', '相册', '拍摄或相册'],
				VideoOfImagesShow: true,
				cameraList: [{
						value: 'back',
						name: '后置摄像头',
						checked: 'true'
					},
					{
						value: 'front',
						name: '前置摄像头'
					},
				],
				cameraIndex: 0,
				videoSuffix: ["AVI", "mov", "rmvb", "rm", "FLV", "mp4", "3GP"],
				suffix:['jpeg','png','jpg','JPG'],
				pageOfficeSuffix: ['doc', 'docx', 'xls', 'xlsx','pdf','PDF']
			}
		},
		created() {
			this.imageList = []; //图片
			this.videoList = []; //视频存放
			this.fileList = []; //文件

			this.ids = [];
			if(this.attachment.fileList.length>0){
				this.setAttachmentData(this.attachment.fileList)
			}
		},
		watch: {
			ids(val) {
				this.$emit('input', val)
			},
		},
		methods: {
			chooseImages() {
				console.log('图片')
				let that = this;
				// 上传图片
				uni.chooseImage({
					count: 1, //默认9
					// sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
					sourceType: ['album', 'camera'], //从相册选择
					success: async (response) => {
						console.log(response)
						let result = await that.fileSizeIsLessLimitSize(response.tempFilePaths[0])
						if (result) {
							showToast('图片质量过大')
							return;
						}
						uni.showLoading({
							mask: true
						})
						let igmFile = response.tempFilePaths;
						console.log(igmFile,'igmFile');
						console.log("===============================");
						let requestData = {
							"masterld":'1772150445546708994',
							"formGroupCode":'XMPG',
							"categoryCode":',XCDCTP,',
							"categoryName":'现场图片'
						}
						let token = appStorage.get('token');
						wx.uploadFile({
							url: `接口地址`,
							filePath: igmFile[0],
							name: 'file',
							formData: requestData,
							header: {
								'Blade-Auth': token
							},
							success: res=>{
								console.log(res)
								uni.hideLoading()
								if (res.code === '200') {
									let imgUrls = res.data
									let info = {
										url: BASE_API_URL + '/minio' + imgUrls.link.substring(that.findCharAt(
											imgUrls.link, '/', 2)),
										id: imgUrls.attachmentId
									}
									that.imageList = that.imageList.concat(info);
									that.ids = that.ids.concat(imgUrls.attachmentId);
									that.$emit('handleHeight')
									that.$_saveAttachInfo(imgUrls.attachmentId,imgUrls.link,imgUrls.originalName)
									// if (that.ids.length >= 5) {
									// 	that.VideoOfImagesShow = false;
									// } else {
									// 	that.VideoOfImagesShow = true;
									// }
								} else {
									showToast('操作失败')
								}
							}
						})




						// const formData = new FormData();
						// formData.append("masterld",'1772150445546708994')
						// formData.append("formGroupCode",'XMPG')
						// formData.append("categoryCode",',XCDCTP,')
						// formData.append("categoryName",'TP')
						// // 这里上传文件
						// formData.appendFile("file",igmFile[0], "file")
						// let data = formData.getData();
						// console.log('转化之后的数据111111',data);
						// let token = appStorage.get('token');
						// console.log("token",token);
						// // const [err, res] = await uploadFile(data);
						// // console.log(res,1666666);
						// wx.request({
						// 	// url: 'http://61.243.2.188:8000/api/miniapp-rc-gz/fileUpload/upload',
						// 	url: 'https://gznd.longersoftware.com/api/miniapp-rc-gz/fileUpload/upload',
						// 	method:'POST',
						// 	header: {
						// 		'content-type': data.contentType,
						// 		'Blade-Auth': token
						// 	},
						// 	data: data.buffer,
						// 	success: function (res) {
						// 		console.log(res,1777777);
						// 		// //上传成功
						// 		// that.setData({
						// 		// 	portrait: res.data.data
						// 		// });
						// 		// wx.showModal({
						// 		// title: '信息',
						// 		// content: res.data.message,
						// 		// confirmText: '确认'
						// 		// }); //showModal
						// 	}
						// });
						
						// const [err, res] = await uploadFile(
						// 	{url:'https://gznd.longersoftware.com',
						// 	filePath:igmFile,
						// 	data:{
						// 		masterld:'1772150445546708994',
						// 		formGroupCode:'XMPG',
						// 		categoryCode:",XCDCTP,",
						// 		categoryName:"现场调查图片,"
						// 	}
						// })
						// const [err, res] =  uploadFile(
						// 	'https://gznd.longersoftware.com',
						// 	igmFile,
						// 	{
						// 		masterld:'1772150445546708994',
						// 		formGroupCode:'XMPG',
						// 		categoryCode:",XCDCTP,",
						// 		categoryName:"现场调查图片,"
						// 	}
						// ).then
						// console.log('uploadFile',err, res);
						// uni.hideLoading()
						// if (err) {
						// 	showToast('操作失败')
						// 	return
						// }
						// if (res.code === 200) {
						// 	let imgUrls = res.data
						// 	let info = {
						// 		url: BASE_API_URL + '/minio' + imgUrls.link.substring(that.findCharAt(
						// 			imgUrls.link, '/', 2)),
						// 		id: imgUrls.attachId
						// 	}
						// 	that.imageList = that.imageList.concat(info);
						// 	that.ids = that.ids.concat(imgUrls.attachId);
						// 	that.$emit('handleHeight')
						// 	that.$_saveAttachInfo(imgUrls.attachId,imgUrls.link,imgUrls.originalName)
						// 	// if (that.ids.length >= 5) {
						// 	// 	that.VideoOfImagesShow = false;
						// 	// } else {
						// 	// 	that.VideoOfImagesShow = true;
						// 	// }
						// } else {
						// 	showToast(res.msg)
						// }
					},
				});
			},
    		// importZcExcel(file){
			// 	// console.log('-file:',file,'-fileList:',fileList)
			// 	const formData = new FormData();
			// 	formData.append('excel', file.raw);
			// 	// console.log('文件:',formData);
			// 	let that=this;
			// 	importZc(formData).then(res => {
			// 		let data=res.data;
			// 		// console.log('xxxx:',data)
			// 		if(data && data.success){
			// 					this.$message.success(data.data);
			// 					that.searchChange();
			// 				}else{
			// 					this.$message.error('message:',data.msg);
			// 				}
			// 	});
			// },
			chooseVideoImage() {
				console.log('this.attachment',this.attachment)
				console.log('this.uniqueId',this.uniqueId)
				uni.showActionSheet({
					title: "选择上传类型",
					itemList: ['图片', '视频', '文件'],
					success: (res) => {
						console.log(res)
						if (res.tapIndex == 0) {
							this.chooseImages()
						} else if (res.tapIndex == 1) {
							this.chooseVideo()
						} else {
							this.chooseFile()
						}
					}
				})
			},
			chooseFile() {
				console.log('文件')
				let vm = this;
				wx.chooseMessageFile({
					count: 1,
					type: 'file',
					success: async (response) => {
						console.log('res--选取文件--', response);
						let result = await vm.fileSizeIsLessLimitSize(response.tempFiles[0].path)
						if (result) {
							showToast('文件质量过大')
							return;
						}
						let igmFile = response.tempFiles;
						uni.showLoading({
							mask: true
						})
						let name=igmFile[0].name;
						const [err, res] = await uploadFileByName(igmFile[0].path, {fileName:name})
						console.log('uploadFileByName',err, res);
						uni.hideLoading()
						if (err) {
							showToast('操作失败')
							return
						}
						console.log('上传文件', res)
						if (res.code === 200) {
							let files = res.data
							let info = {
								url: BASE_API_URL + '/minio' + files.link.substring(vm.findCharAt(files
									.link, '/', 2)),
								id: files.attachId,
								name:name
								// name:'文件'
							}
							vm.fileList = vm.fileList.concat(info);
							vm.ids = vm.ids.concat(files.attachId);
							vm.$emit('handleHeight')
							vm.$_saveAttachInfo(files.attachId,files.link,files.originalName)
						} else {
							showToast(res.msg)
						}
					}
				})
			},
			chooseImages2() {
				console.log('图片')
				let that = this;
				// 上传图片
				uni.chooseImage({
					count: 1, //默认9
					// sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
					sourceType: ['album', 'camera'], //从相册选择
					success: async (response) => {
						console.log(response)
						let result = await that.fileSizeIsLessLimitSize(response.tempFilePaths[0])
						if (result) {
							showToast('图片质量过大')
							return;
						}
						uni.showLoading({
							mask: true
						})
						console.log(response,'response');
						let igmFile = response.tempFilePaths;
						console.log(igmFile,'igmFile');
						// const formData = new FormData();
						// formData.append("file",igmFile)
						// const [err, res] = await uploadFile(
						// 	{url:'https://gznd.longersoftware.com',
						// 	filePath:igmFile,
						// 	data:{
						// 		masterld:'1772150445546708994',
						// 		formGroupCode:'XMPG',
						// 		categoryCode:",XCDCTP,",
						// 		categoryName:"现场调查图片,"
						// 	}
						// })
						const [err, res] =  uploadFile(
							'https://gznd.longersoftware.com',
							igmFile,
							{
								masterld:'1772150445546708994',
								formGroupCode:'XMPG',
								categoryCode:",XCDCTP,",
								categoryName:"现场调查图片,"
							}
						).then
						// const [err, res] = await uploadFile('1772150445546708994','XMPG',formData,",XCDCTP,","现场调查图片,")
						// const [err, res] = await uploadFile(igmFile[0], {})
						console.log('uploadFile',err, res);
						uni.hideLoading()
						if (err) {
							showToast('操作失败')
							return
						}
						if (res.code === 200) {
							let imgUrls = res.data
							let info = {
								url: BASE_API_URL + '/minio' + imgUrls.link.substring(that.findCharAt(
									imgUrls.link, '/', 2)),
								id: imgUrls.attachId
							}
							that.imageList = that.imageList.concat(info);
							that.ids = that.ids.concat(imgUrls.attachId);
							that.$emit('handleHeight')
							that.$_saveAttachInfo(imgUrls.attachId,imgUrls.link,imgUrls.originalName)
							// if (that.ids.length >= 5) {
							// 	that.VideoOfImagesShow = false;
							// } else {
							// 	that.VideoOfImagesShow = true;
							// }
						} else {
							showToast(res.msg)
						}
					},
				});
			},
			chooseVideo() {
				console.log('视频')
				let that = this;
				// 上传视频
				uni.chooseVideo({
					maxDuration: 60,
					count: 1,
					camera: this.cameraList[this.cameraIndex].value,
					sourceType: ['album'],
					success: async (responent) => {
						console.log(responent)
						let videoFile = responent.tempFilePath;
						console.log(videoFile)
						let result = await that.fileSizeIsLessLimitSize(responent.tempFilePath)
						if (result) {
							showToast('图片质量过大')
							return;
						}
						uni.showLoading({
							mask: true
						})
						const [err, res] = await uploadFile(videoFile, {})
						uni.hideLoading()
						console.log(res)
						if (err) {
							showToast('操作失败')
							return
						}
						if (res.code === 200) {
							let videoUrls = res.data //百度支持
							let info = {
								url: BASE_API_URL + '/minio' + videoUrls.link.substring(that.findCharAt(
									videoUrls.link, '/', 2)),
								id: videoUrls.attachId
							}
							that.videoList = that.videoList.concat(info);
							that.ids = that.ids.concat(videoUrls.attachId);
							that.$emit('handleHeight')
							that.$_saveAttachInfo(videoUrls.attachId,videoUrls.link,videoUrls.originalName)
							// if (that.ids.length >= 5) {
							// 	that.VideoOfImagesShow = false;
							// } else {
							// 	that.VideoOfImagesShow = true;
							// }
						} else {
							showToast(res.msg)
						}

						// this.src = responent.tempFilePath;  //头条
					}
				})
			},
			previewImage: function(e) {
				//预览图片
				var current = e.target.dataset.src
				let list = [];
				this.imageList.forEach((item) => {
					list.push(item.url)
				})
				uni.previewImage({
					current: current,
					urls: list
				})
			},
			deleteImage(index, item) {
				console.log(item)
				let that = this;
				uni.showModal({
					title: "提示",
					content: "是否要删除该图片",
					success: async (res) => {
						if (res.confirm) {
							const [error, response] = await deleteAttachment({attachmentId:item.id})
							console.log(response)
							if (error) {
								showToast('操作失败')
								return
							}
							if (response.code === 200) {
							that.imageList.splice(index, 1);
							that.ids.splice(that.ids.indexOf(item.id), 1);
							// if (that.ids.length >= 5) {
							// 	that.VideoOfImagesShow = false;
							// } else {
							// 	that.VideoOfImagesShow = true;
							// }
							showToast(response.msg)
							that.$emit('handleHeight')
							}
						}
					}
				})
			},
			deleteVideo(index, item) {
				let that = this;
				uni.showModal({
					title: "提示",
					content: "是否要删除此视频",
					success: async (res) => {
						if (res.confirm) {
							const [error, response] = await deleteAttachment({attachmentId:item.id})
							if (error) {
								showToast('操作失败')
								return
							}
							if (response.code === 200) {
							that.videoList.splice(index, 1);
							that.ids.splice(that.ids.indexOf(item.id), 1);
							// if (that.ids.length >= 5) {
							// 	that.VideoOfImagesShow = false;
							// } else {
							// 	that.VideoOfImagesShow = true;
							// }
							showToast(response.msg)
							that.$emit('handleHeight')
							}
						}
					}
				})
			},
			fileActive(file) {
				let that=this;
				uni.showActionSheet({
					title: "文件操作",
					itemList: ['查看'],
					success: (res) => {
						console.log(res)
						if (res.tapIndex == 0) {
							console.log('查看', file)
							this.downloadFilePreview(file)
						}
					}
				})
			},
			downloadFilePreview (file) {
			      uni.showLoading({
					mask: true
				  })
			      wx.downloadFile({
			        url: file.url, // 这里换上自己的pdf地址
			        header: {
			          'content-type': 'application/json'
			        },
			        success: function (res) {
						console.log(res)
			          var Path = res.tempFilePath // 返回的文件临时地址,用于后面打开本地预览所用
					
						wx.openDocument({
							filePath: Path,
							success: function (res) {
							  uni.hideLoading()
							},
							fail: function (res) {
							  showToast('打开失败')
							}
						})			
					  
			        },
			        fail: function (res) {
					  showToast('下载失败')
			        }
			      })
			    },
			deleteFile(index, item) {
				let that = this;
				uni.showModal({
					title: "提示",
					content: "是否要删除此文件",
					success: async (res) => {
						if (res.confirm) {
							const [error, response] = await deleteAttachment({attachmentId:item.id})
							if (error) {
								showToast('操作失败')
								return
							}
							if (response.code === 200) {
							that.fileList.splice(index, 1);
							that.ids.splice(that.ids.indexOf(item.id), 1);
							that.$emit('handleHeight')
							showToast(response.msg)
							}
						}
					}
				})
			},
			async $_saveAttachInfo(id,link,originalName){
				let data={
					bladeAttachmentPath:link,
					bladeAttachmentId:id,
					dictCode:this.attachment.dictCode,
					categoryCode:this.attachment.categoryCode,
					dictName:this.attachment.dictName,
					uniqueId:this.uniqueId,
					originalName:originalName
				}
				const [err, res] = await saveAttachInfo(data)
				if (err) {
					return
				}
				if (res.code === 200) {
					
				}
			},
			//判断文件大小是否满足需求,limitSize的单位是kb
			fileSizeIsLessLimitSize(filePath) {
				//获取文件信息
				let result = false;
				return new Promise((resolve, reject) => {
					uni.getFileInfo({
						filePath: filePath,
						success: (res) => {
							console.log("文件大小", res.size / 1024, 'kb');
							if (res.size / 1024 > 1024 * 10) {
								result = true;
							}
							resolve(result);
						},
						fail: (err) => {
							reject(result)
						}
					})
				})
			},
			findCharAt(str, cha, num) {
				var x = str.indexOf(cha);
				for (var i = 0; i < num; i++) {
					x = str.indexOf(cha, x + 1);
				}
				return x;
			},
			setAttachmentData(data){
				console.log('图片数据',data)
				let that=this;
				data.forEach(item=>{
					let suffix = item.originalName.substring(item.originalName.lastIndexOf('.') + 1, item.originalName.length);
					let info = {
						// url: BASE_API_URL + '/minio' + item.bladeAttachmentPath.substring(that.findCharAt(item
						// 	.bladeAttachmentPath, '/', 2)),
						url: BASE_API_URL + '/minio' + item.bladeAttachmentPath,
						id: item.bladeAttachmentId,
						name:item.originalName
					}
					that.ids = that.ids.concat(item.bladeAttachmentId);
					if(this.suffix.indexOf(suffix)>=0){
						that.imageList = that.imageList.concat(info);
					} else if(this.videoSuffix.indexOf(suffix)>=0){
						that.videoList = that.videoList.concat(info);
					}else if(this.pageOfficeSuffix.indexOf(suffix)>=0){
						that.fileList = that.fileList.concat(info);
					}
				})	
			}
		}
	}
</script>

<style>
	.uni-file-picker__container {
		display: flex;
		box-sizing: border-box;
		flex-wrap: wrap;
		margin: -5rpx;
		justify-content: start;
	}

	.file-picker__box {
		position: relative;
		width: 200rpx;
		height: 0;
		padding-top: 200rpx;
		box-sizing: border-box;
	}

	.file-picker__box-content {
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		margin: 10rpx;
		border: 1rpx #eee solid;
		border-radius: 5px;
		overflow: hidden;
	}

	.file-image {
		width: 100%;
		height: 100%;
	}

	.is-add {
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.icon-add {
		width: 50rpx;
		height: 5rpx;
		background-color: #f1f1f1;
		border-radius: 2px;
	}

	.rotate {
		position: absolute;
		transform: rotate(90deg);
	}

	.icon-del-box {
		display: flex;
		align-items: center;
		justify-content: center;
		position: absolute;
		top: 3rpx;
		right: 3rpx;
		height: 26rpx;
		width: 26rpx;
		border-radius: 50%;
		background-color: rgba(0, 0, 0, 0.5);
		z-index: 2;
		transform: rotate(-45deg);
	}

	.icon-del {
		width: 15rpx;
		height: 2rpx;
		background-color: #fff;
		border-radius: 2rpx;
	}

	,
	.file_list__box {
		margin-bottom: 20rpx;
		display: flex;
		align-items: center;
		position: relative;
	}

	.file_list__box text {
		font-size: 32rpx;
		padding-left: 5rpx;
		color: #949F94;
		overflow: hidden;
		word-break: break-all;
		/* break-all(允许在单词内换行。) */
		text-overflow: ellipsis;
		/* 超出部分省略号 */
		display: -webkit-box;
		/** 对象作为伸缩盒子模型显示 **/
		-webkit-box-orient: vertical;
		/** 设置或检索伸缩盒对象的子元素的排列方式 **/
		-webkit-line-clamp: 1;
		/** 显示的行数 **/
	}

	.file_list__box .delete_file {
		position: absolute;
		right: -15rpx;
		z-index: 2;
	}
</style>

4.注意:文件和上传视频代码未修改

5.formdata

 

const mimeMap = require('./mimeMap.js')

function FormData(){

  let fileManager = wx.getFileSystemManager();

  let data = {};

  let files = [];

  this.append = (name, value)=>{

    data[name] = value;

    return true;

  }

  this.appendFile = (name, path, fileName)=>{

    let buffer = fileManager.readFileSync(path);

    if(Object.prototype.toString.call(buffer).indexOf("ArrayBuffer") < 0){

      return false;

    }

    if(!fileName){

      fileName = getFileNameFromPath(path);

    }

    files.push({

      name: name,

      buffer: buffer,

      fileName: fileName

    });

    return true;

  }

  this.getData = ()=>convert(data, files)

}

function getFileNameFromPath(path){

  let idx=path.lastIndexOf("/");

  return path.substr(idx+1);

}

function convert(data, files){

  let boundaryKey = 'wxmpFormBoundary' + randString(); // 数据分割符,一般是随机的字符串

  let boundary = '--' + boundaryKey;

  let endBoundary = boundary + '--';

  let postArray = [];

  //拼接参数

  if(data && Object.prototype.toString.call(data) == "[object Object]"){

    for(let key in data){

      postArray = postArray.concat(formDataArray(boundary, key, data[key]));

    }

  }

  //拼接文件

  if(files && Object.prototype.toString.call(files) == "[object Array]"){

    for(let i in files){

      let file = files[i];

      postArray = postArray.concat(formDataArray(boundary, file.name, file.buffer, file.fileName));

    }

  }

  //结尾

  let endBoundaryArray = [];

  endBoundaryArray.push(...endBoundary.toUtf8Bytes());

  postArray = postArray.concat(endBoundaryArray);

  return {

    contentType: 'multipart/form-data; boundary=' + boundaryKey,

    buffer: new Uint8Array(postArray).buffer

  }

}

function randString() {

  var result = '';

  var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

  for (var i = 17; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];

  return result;

}

function formDataArray(boundary, name, value, fileName){

  let dataString = '';

  let isFile = !!fileName;

  dataString += boundary + '\r\n';

  dataString += 'Content-Disposition: form-data; name="' + name + '"';

  if (isFile){

    dataString += '; filename="' + fileName + '"' + '\r\n';

    dataString += 'Content-Type: ' + getFileMime(fileName) + '\r\n\r\n';

  }

  else{

    dataString += '\r\n\r\n';

    dataString += value;

  }

  var dataArray = [];

  dataArray.push(...dataString.toUtf8Bytes());

  if (isFile) {

    let fileArray = new Uint8Array(value);

    dataArray = dataArray.concat(Array.prototype.slice.call(fileArray));

  }

  dataArray.push(..."\r".toUtf8Bytes());

  dataArray.push(..."\n".toUtf8Bytes());

  return dataArray;

}

function getFileMime(fileName){

  let idx = fileName.lastIndexOf(".");

  let mime = mimeMap[fileName.substr(idx)];

  return mime?mime:"application/octet-stream"

}

String.prototype.toUtf8Bytes = function(){

  var str = this;

  var bytes = [];

  for (var i = 0; i < str.length; i++) {

    bytes.push(...str.utf8CodeAt(i));

    if (str.codePointAt(i) > 0xffff) {

      i++;

    }

  }

  return bytes;

}

String.prototype.utf8CodeAt = function(i) {

  var str = this;

  var out = [], p = 0;

  var c = str.charCodeAt(i);

  if (c < 128) {

    out[p++] = c;

  } else if (c < 2048) {

    out[p++] = (c >> 6) | 192;

    out[p++] = (c & 63) | 128;

  } else if (

      ((c & 0xFC00) == 0xD800) && (i + 1) < str.length &&

      ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {

    // Surrogate Pair

    c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);

    out[p++] = (c >> 18) | 240;

    out[p++] = ((c >> 12) & 63) | 128;

    out[p++] = ((c >> 6) & 63) | 128;

    out[p++] = (c & 63) | 128;

  } else {

    out[p++] = (c >> 12) | 224;

    out[p++] = ((c >> 6) & 63) | 128;

    out[p++] = (c & 63) | 128;

  }

  return out;

};


 

module.exports = FormData;

6.mimeMap.js

module.exports = {

  "0.001": "application/x-001",

  "0.323": "text/h323",

  "0.907": "drawing/907",

  ".acp": "audio/x-mei-aac",

  ".aif": "audio/aiff",

  ".aiff": "audio/aiff",

  ".asa": "text/asa",

  ".asp": "text/asp",

  ".au": "audio/basic",

  ".awf": "application/vnd.adobe.workflow",

  ".bmp": "application/x-bmp",

  ".c4t": "application/x-c4t",

  ".cal": "application/x-cals",

  ".cdf": "application/x-netcdf",

  ".cel": "application/x-cel",

  ".cg4": "application/x-g4",

  ".cit": "application/x-cit",

  ".cml": "text/xml",

  ".cmx": "application/x-cmx",

  ".crl": "application/pkix-crl",

  ".csi": "application/x-csi",

  ".cut": "application/x-cut",

  ".dbm": "application/x-dbm",

  ".dcd": "text/xml",

  ".der": "application/x-x509-ca-cert",

  ".dib": "application/x-dib",

  ".doc": "application/msword",

  ".drw": "application/x-drw",

  ".dwf": "Model/vnd.dwf",

  ".dwg": "application/x-dwg",

  ".dxf": "application/x-dxf",

  ".emf": "application/x-emf",

  ".ent": "text/xml",

  ".eps": "application/x-ps",

  ".etd": "application/x-ebx",

  ".fax": "image/fax",

  ".fif": "application/fractals",

  ".frm": "application/x-frm",

  ".gbr": "application/x-gbr",

  ".gif": "image/gif",

  ".gp4": "application/x-gp4",

  ".hmr": "application/x-hmr",

  ".hpl": "application/x-hpl",

  ".hrf": "application/x-hrf",

  ".htc": "text/x-component",

  ".html": "text/html",

  ".htx": "text/html",

  ".ico": "image/x-icon",

  ".iff": "application/x-iff",

  ".igs": "application/x-igs",

  ".img": "application/x-img",

  ".isp": "application/x-internet-signup",

  ".java": "java/*",

  ".jpe": "image/jpeg",

  ".jpeg": "image/jpeg",

  ".jpg": "application/x-jpg",

  ".jsp": "text/html",

  ".lar": "application/x-laplayer-reg",

  ".lavs": "audio/x-liquid-secure",

  ".lmsff": "audio/x-la-lms",

  ".ltr": "application/x-ltr",

  ".m2v": "video/x-mpeg",

  ".m4e": "video/mpeg4",

  ".man": "application/x-troff-man",

  ".mdb": "application/msaccess",

  ".mfp": "application/x-shockwave-flash",

  ".mhtml": "message/rfc822",

  ".mid": "audio/mid",

  ".mil": "application/x-mil",

  ".mnd": "audio/x-musicnet-download",

  ".mocha": "application/x-javascript",

  ".mp1": "audio/mp1",

  ".mp2v": "video/mpeg",

  ".mp4": "video/mpeg4",

  ".mpd": "application/vnd.ms-project",

  ".mpeg": "video/mpg",

  ".mpga": "audio/rn-mpeg",

  ".mps": "video/x-mpeg",

  ".mpv": "video/mpg",

  ".mpw": "application/vnd.ms-project",

  ".mtx": "text/xml",

  ".net": "image/pnetvue",

  ".nws": "message/rfc822",

  ".out": "application/x-out",

  ".p12": "application/x-pkcs12",

  ".p7c": "application/pkcs7-mime",

  ".p7r": "application/x-pkcs7-certreqresp",

  ".pc5": "application/x-pc5",

  ".pcl": "application/x-pcl",

  ".pdf": "application/pdf",

  ".pdx": "application/vnd.adobe.pdx",

  ".pgl": "application/x-pgl",

  ".pko": "application/vnd.ms-pki.pko",

  ".plg": "text/html",

  ".plt": "application/x-plt",

  ".png": "application/x-png",

  ".ppa": "application/vnd.ms-powerpoint",

  ".pps": "application/vnd.ms-powerpoint",

  ".ppt": "application/x-ppt",

  ".prf": "application/pics-rules",

  ".prt": "application/x-prt",

  ".ps": "application/postscript",

  ".pwz": "application/vnd.ms-powerpoint",

  ".ra": "audio/vnd.rn-realaudio",

  ".ras": "application/x-ras",

  ".rdf": "text/xml",

  ".red": "application/x-red",

  ".rjs": "application/vnd.rn-realsystem-rjs",

  ".rlc": "application/x-rlc",

  ".rm": "application/vnd.rn-realmedia",

  ".rmi": "audio/mid",

  ".rmm": "audio/x-pn-realaudio",

  ".rms": "application/vnd.rn-realmedia-secure",

  ".rmx": "application/vnd.rn-realsystem-rmx",

  ".rp": "image/vnd.rn-realpix",

  ".rsml": "application/vnd.rn-rsml",

  ".rtf": "application/msword",

  ".rv": "video/vnd.rn-realvideo",

  ".sat": "application/x-sat",

  ".sdw": "application/x-sdw",

  ".slb": "application/x-slb",

  ".slk": "drawing/x-slk",

  ".smil": "application/smil",

  ".snd": "audio/basic",

  ".sor": "text/plain",

  ".spl": "application/futuresplash",

  ".ssm": "application/streamingmedia",

  ".stl": "application/vnd.ms-pki.stl",

  ".sty": "application/x-sty",

  ".swf": "application/x-shockwave-flash",

  ".tg4": "application/x-tg4",

  ".tif": "image/tiff",

  ".tiff": "image/tiff",

  ".top": "drawing/x-top",

  ".tsd": "text/xml",

  ".uin": "application/x-icq",

  ".vcf": "text/x-vcard",

  ".vdx": "application/vnd.visio",

  ".vpg": "application/x-vpeg005",

  ".vsd": "application/x-vsd",

  ".vst": "application/vnd.visio",

  ".vsw": "application/vnd.visio",

  ".vtx": "application/vnd.visio",

  ".wav": "audio/wav",

  ".wb1": "application/x-wb1",

  ".wb3": "application/x-wb3",

  ".wiz": "application/msword",

  ".wk4": "application/x-wk4",

  ".wks": "application/x-wks",

  ".wma": "audio/x-ms-wma",

  ".wmf": "application/x-wmf",

  ".wmv": "video/x-ms-wmv",

  ".wmz": "application/x-ms-wmz",

  ".wpd": "application/x-wpd",

  ".wpl": "application/vnd.ms-wpl",

  ".wr1": "application/x-wr1",

  ".wrk": "application/x-wrk",

  ".ws2": "application/x-ws",

  ".wsdl": "text/xml",

  ".xdp": "application/vnd.adobe.xdp",

  ".xfd": "application/vnd.adobe.xfd",

  ".xhtml": "text/html",

  ".xls": "application/x-xls",

  ".xml": "text/xml",

  ".xq": "text/xml",

  ".xquery": "text/xml",

  ".xsl": "text/xml",

  ".xwd": "application/x-xwd",

  ".sis": "application/vnd.symbian.install",

  ".x_t": "application/x-x_t",

  ".apk": "application/vnd.android.package-archive",

  "0.301": "application/x-301",

  "0.906": "application/x-906",

  ".a11": "application/x-a11",

  ".ai": "application/postscript",

  ".aifc": "audio/aiff",

  ".anv": "application/x-anv",

  ".asf": "video/x-ms-asf",

  ".asx": "video/x-ms-asf",

  ".avi": "video/avi",

  ".biz": "text/xml",

  ".bot": "application/x-bot",

  ".c90": "application/x-c90",

  ".cat": "application/vnd.ms-pki.seccat",

  ".cdr": "application/x-cdr",

  ".cer": "application/x-x509-ca-cert",

  ".cgm": "application/x-cgm",

  ".class": "java/*",

  ".cmp": "application/x-cmp",

  ".cot": "application/x-cot",

  ".crt": "application/x-x509-ca-cert",

  ".css": "text/css",

  ".dbf": "application/x-dbf",

  ".dbx": "application/x-dbx",

  ".dcx": "application/x-dcx",

  ".dgn": "application/x-dgn",

  ".dll": "application/x-msdownload",

  ".dot": "application/msword",

  ".dtd": "text/xml",

  ".dwf": "application/x-dwf",

  ".dxb": "application/x-dxb",

  ".edn": "application/vnd.adobe.edn",

  ".eml": "message/rfc822",

  ".epi": "application/x-epi",

  ".eps": "application/postscript",

  ".exe": "application/x-msdownload",

  ".fdf": "application/vnd.fdf",

  ".fo": "text/xml",

  ".g4": "application/x-g4",

  ".tif": "image/tiff",

  ".gl2": "application/x-gl2",

  ".hgl": "application/x-hgl",

  ".hpg": "application/x-hpgl",

  ".hqx": "application/mac-binhex40",

  ".hta": "application/hta",

  ".htm": "text/html",

  ".htt": "text/webviewhtml",

  ".icb": "application/x-icb",

  ".ico": "application/x-ico",

  ".ig4": "application/x-g4",

  ".iii": "application/x-iphone",

  ".ins": "application/x-internet-signup",

  ".IVF": "video/x-ivf",

  ".jfif": "image/jpeg",

  ".jpe": "application/x-jpe",

  ".jpg": "image/jpeg",

  ".js": "application/x-javascript",

  ".la1": "audio/x-liquid-file",

  ".latex": "application/x-latex",

  ".lbm": "application/x-lbm",

  ".ls": "application/x-javascript",

  ".m1v": "video/x-mpeg",

  ".m3u": "audio/mpegurl",

  ".mac": "application/x-mac",

  ".math": "text/xml",

  ".mdb": "application/x-mdb",

  ".mht": "message/rfc822",

  ".mi": "application/x-mi",

  ".midi": "audio/mid",

  ".mml": "text/xml",

  ".mns": "audio/x-musicnet-stream",

  ".movie": "video/x-sgi-movie",

  ".mp2": "audio/mp2",

  ".mp3": "audio/mp3",

  ".mpa": "video/x-mpg",

  ".mpe": "video/x-mpeg",

  ".mpg": "video/mpg",

  ".mpp": "application/vnd.ms-project",

  ".mpt": "application/vnd.ms-project",

  ".mpv2": "video/mpeg",

  ".mpx": "application/vnd.ms-project",

  ".mxp": "application/x-mmxp",

  ".nrf": "application/x-nrf",

  ".odc": "text/x-ms-odc",

  ".p10": "application/pkcs10",

  ".p7b": "application/x-pkcs7-certificates",

  ".p7m": "application/pkcs7-mime",

  ".p7s": "application/pkcs7-signature",

  ".pci": "application/x-pci",

  ".pcx": "application/x-pcx",

  ".pdf": "application/pdf",

  ".pfx": "application/x-pkcs12",

  ".pic": "application/x-pic",

  ".pl": "application/x-perl",

  ".pls": "audio/scpls",

  ".png": "image/png",

  ".pot": "application/vnd.ms-powerpoint",

  ".ppm": "application/x-ppm",

  ".ppt": "application/vnd.ms-powerpoint",

  ".pr": "application/x-pr",

  ".prn": "application/x-prn",

  ".ps": "application/x-ps",

  ".ptn": "application/x-ptn",

  ".r3t": "text/vnd.rn-realtext3d",

  ".ram": "audio/x-pn-realaudio",

  ".rat": "application/rat-file",

  ".rec": "application/vnd.rn-recording",

  ".rgb": "application/x-rgb",

  ".rjt": "application/vnd.rn-realsystem-rjt",

  ".rle": "application/x-rle",

  ".rmf": "application/vnd.adobe.rmf",

  ".rmj": "application/vnd.rn-realsystem-rmj",

  ".rmp": "application/vnd.rn-rn_music_package",

  ".rmvb": "application/vnd.rn-realmedia-vbr",

  ".rnx": "application/vnd.rn-realplayer",

  ".rpm": "audio/x-pn-realaudio-plugin",

  ".rt": "text/vnd.rn-realtext",

  ".rtf": "application/x-rtf",

  ".sam": "application/x-sam",

  ".sdp": "application/sdp",

  ".sit": "application/x-stuffit",

  ".sld": "application/x-sld",

  ".smi": "application/smil",

  ".smk": "application/x-smk",

  ".sol": "text/plain",

  ".spc": "application/x-pkcs7-certificates",

  ".spp": "text/xml",

  ".sst": "application/vnd.ms-pki.certstore",

  ".stm": "text/html",

  ".svg": "text/xml",

  ".tdf": "application/x-tdf",

  ".tga": "application/x-tga",

  ".tif": "application/x-tif",

  ".tld": "text/xml",

  ".torrent": "application/x-bittorrent",

  ".txt": "text/plain",

  ".uls": "text/iuls",

  ".vda": "application/x-vda",

  ".vml": "text/xml",

  ".vsd": "application/vnd.visio",

  ".vss": "application/vnd.visio",

  ".vst": "application/x-vst",

  ".vsx": "application/vnd.visio",

  ".vxml": "text/xml",

  ".wax": "audio/x-ms-wax",

  ".wb2": "application/x-wb2",

  ".wbmp": "image/vnd.wap.wbmp",

  ".wk3": "application/x-wk3",

  ".wkq": "application/x-wkq",

  ".wm": "video/x-ms-wm",

  ".wmd": "application/x-ms-wmd",

  ".wml": "text/vnd.wap.wml",

  ".wmx": "video/x-ms-wmx",

  ".wp6": "application/x-wp6",

  ".wpg": "application/x-wpg",

  ".wq1": "application/x-wq1",

  ".wri": "application/x-wri",

  ".ws": "application/x-ws",

  ".wsc": "text/scriptlet",

  ".wvx": "video/x-ms-wvx",

  ".xdr": "text/xml",

  ".xfdf": "application/vnd.adobe.xfdf",

  ".xls": "application/vnd.ms-excel",

  ".xlw": "application/x-xlw",

  ".xpl": "audio/scpls",

  ".xql": "text/xml",

  ".xsd": "text/xml",

  ".xslt": "text/xml",

  ".x_b": "application/x-x_b",

  ".sisx": "application/vnd.symbian.install",

  ".ipa": "application/vnd.iphone",

  ".xap": "application/x-silverlight-app",

  ".zip": "application/x-zip-compressed",

}