【微信小程序】怎样创建formdata对象,并通过 wx.request 发送file文件

2024-01-27 09:44

本文主要是介绍【微信小程序】怎样创建formdata对象,并通过 wx.request 发送file文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、场景

  1. 业务需求:微信小程序开发需要选择本地照片file连同一些表单数据,通过接口发送给服务器

  2. 问题:
    因涉及到域名安全问题以及并不是单独上传图片,不能使用 wx.uploadFile 。
    微信本身没有FormData对象,无法使用 new FormData
    后端接口需要接收一个file, 所以只能想办法,通过wx.request 发送 multipart/form-data 请求

二、解决办法(使用方法)

  1. 手动写一个formdata文件,然后引入。

原作者参考微信社区、大神的github,整理出来的formdata.js的用法(就佩服善于整理的人,我有时候都看不懂大神写的什么,谈何整理!!)

request 请求:
formdata.js 文件
mimeMap 文件

这是原作者的用法

import FormData from './FormData/index.js'// 上传图片
export function uploadFile(newUrl){ // newUrl是本地文件的 tmp 地址 let formData = new FormData();// 用法// formData.append("name", "value");      // value 表单值// formData.appendFile("file", filepath); // filepath 文件路径formData.appendFile("multipartFile", newUrl);// formData.getData() => { //   buffer:<ArrayBuffer>[], // buffer	表单数据的ArrayBuffer对象 //   contentType: string,    // http请求Content-Type头部内容// } const data = formData.getData();return new Promise((resolve,reject)=>{wx.request({url:"https://xxxxx.xxxxxx.xxxxx/api/img/upload",method: 'POST',header: {'content-type': data.contentType},data: data.buffer,success(res) {if(res.success) console.log("上传成功")}});})
}

因为我的需求是上传多张图片,所以会多一步

import FormData from './FormData/index.js'// 上传图片
export function uploadFile(){ // newUrl是本地文件的 tmp 地址 let formdata = new FormData();let data={}  //data是要传给服务器的json对象,替换成自己的就行for (let i in data) { //这里需要遍历对象,让每一个参数变成formdata格式if(i=='files'){ //files是我自定义的要上传的图片数组字段名data.files.forEach(filepath=>{ //这里需要每一张遍历一下,就是普通的字符串数组formdata.appendFile("files", filepath, "");})}else{ //这里是其他参数,正常拼接就行formdata.append(i,data[i]);}}let newdata = formdata.getData(); //下面的操作都差不多了,注意如果是跟我一样的多文件请求记得把作者下面的拼接注掉// 用法// formData.append("name", "value");      // value 表单值// formData.appendFile("file", filepath); // filepath 文件路径// formData.appendFile("multipartFile", newUrl); // formData.getData() => { //   buffer:<ArrayBuffer>[], // buffer	表单数据的ArrayBuffer对象 //   contentType: string,    // http请求Content-Type头部内容// } // const data = formData.getData();return new Promise((resolve,reject)=>{wx.request({url:"https://xxxxx.xxxxxx.xxxxx/api/img/upload",method: 'POST',header: {'content-type': newdata.contentType},data: newdata.buffer,success(res) {//没什么意外的话,应该会请求成功。。看起来简单吧(*^▽^*)if(res.success) console.log("上传成功")}});})
}

千万记得在要用到的js文件中引用,我将formdata.js放在了跟目录下的自己创建的utils文件夹
在这里插入图片描述

三、核心代码(你只需要复制粘贴就可以)

formdata.js:

import mimeMap from './mimeMap'function FormData(){let fileManager = wx.getFileSystemManager();let data = {};let files = [];this.append = (name, value)=>{data[name] = value;return true;}this.appendFile = (name, path)=>{let buffer = fileManager.readFileSync(path);if(Object.prototype.toString.call(buffer).indexOf("ArrayBuffer") < 0){return false;}files.push({name: name,buffer: buffer,fileName: getFileNameFromPath(path)});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 = [];for (var i = 0; i < endBoundary.length; i++) { // 最后取出结束boundary的charCodeendBoundaryArray.push(...endBoundary.utf8CodeAt(i));}postArray = postArray.concat(endBoundaryArray);return {contentType: 'multipart/form-data; boundary=' + boundaryKey,buffer: new Uint8Array(postArray).buffer}
}function randString() {let res = "";for (let i = 0; i < 17; i++) {let n = parseInt(Math.random() * 62);if (n <= 9) {res += n;}else if (n <= 35) {res += String.fromCharCode(n + 55);}else {res += String.fromCharCode(n + 61);}}return res;
}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 = [];for (var i = 0; i < dataString.length; i++) { // 取出文本的charCode(10进制)dataArray.push(...dataString.utf8CodeAt(i));}if (isFile) {let fileArray = new Uint8Array(value);dataArray = dataArray.concat(Array.prototype.slice.call(fileArray));}dataArray.push(..."\r".utf8CodeAt());dataArray.push(..."\n".utf8CodeAt());return dataArray;
}function getFileMime(fileName){let idx = fileName.lastIndexOf(".");let mime = mimeMap[fileName.substr(idx)];return mime?mime:"application/octet-stream"
}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 Pairc = 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;
};export default FormData;

2.mimeMap.js

const mimeMap = {"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",
}
export default mimeMap;

注意:
因源码无法直接在项目中使用,本文代码在源码的基础上完善了一些改动的基础上完善了一些改动(不出意外的话应该是可以直接使用的,如果不行的话在一起探讨咯)。

如果本文代码无法满足您的需求,还请移步去看一下源码 github https://github.com/zlyboy/wx-formdata

这篇关于【微信小程序】怎样创建formdata对象,并通过 wx.request 发送file文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/649858

相关文章

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他

JavaScript对象转数组的三种方法实现

《JavaScript对象转数组的三种方法实现》本文介绍了在JavaScript中将对象转换为数组的三种实用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录方法1:使用Object.keys()和Array.map()方法2:使用Object.entr

idea+spring boot创建项目的搭建全过程

《idea+springboot创建项目的搭建全过程》SpringBoot是Spring社区发布的一个开源项目,旨在帮助开发者快速并且更简单的构建项目,:本文主要介绍idea+springb... 目录一.idea四种搭建方式1.Javaidea命名规范2JavaWebTomcat的安装一.明确tomcat

java程序远程debug原理与配置全过程

《java程序远程debug原理与配置全过程》文章介绍了Java远程调试的JPDA体系,包含JVMTI监控JVM、JDWP传输调试命令、JDI提供调试接口,通过-Xdebug、-Xrunjdwp参数配... 目录背景组成模块间联系IBM对三个模块的详细介绍编程使用总结背景日常工作中,每个程序员都会遇到bu

Java发送SNMP至交换机获取交换机状态实现方式

《Java发送SNMP至交换机获取交换机状态实现方式》文章介绍使用SNMP4J库(2.7.0)通过RCF1213-MIB协议获取交换机单/多路状态,需开启SNMP支持,重点对比SNMPv1、v2c、v... 目录交换机协议SNMP库获取交换机单路状态获取交换机多路状态总结交换机协议这里使用的交换机协议为常

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

使用MapStruct实现Java对象映射的示例代码

《使用MapStruct实现Java对象映射的示例代码》本文主要介绍了使用MapStruct实现Java对象映射的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、什么是 MapStruct?二、实战演练:三步集成 MapStruct第一步:添加 Mave

Java中实现对象的拷贝案例讲解

《Java中实现对象的拷贝案例讲解》Java对象拷贝分为浅拷贝(复制值及引用地址)和深拷贝(递归复制所有引用对象),常用方法包括Object.clone()、序列化及JSON转换,需处理循环引用问题,... 目录对象的拷贝简介浅拷贝和深拷贝浅拷贝深拷贝深拷贝和循环引用总结对象的拷贝简介对象的拷贝,把一个