Taro自定义FromData实现本地路径转换为文件

在用Taro写头像上传功能时,因为需要对获得的图片进行剪切成圆形或方形。使用组件剪切完之后返回的是一个本地图片的相对路径。这个时候我们就需要自己实现将本地路径重新转换为二进制文件。

引入两个js文件

mimeMap.js

javascript 复制代码
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",
}

fromdata.js

javascript 复制代码
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); // 读取文件内容到 buffer
    if (Object.prototype.toString.call(buffer).indexOf("ArrayBuffer") < 0) {
      return false;// 如果不是 ArrayBuffer 类型,返回 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'; // 数据分割符,一般是随机的字符串
  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;

这两个js文件引入之后就可以直接 使用转换了

具体代码使用

javascript 复制代码
import FormData from "../../../../utils/formdata";

//调用方法
const cutImage = async (data: any) => {   //data为图片路径
    const formData = new FormData();
    //根据自己引入的文件,创建了一个新的 FormData 对象
    formData.appendFile("imgs", data, "test.png");
    //将一个文件数据添加到 FormData 对象中。
    const convertData = formData.getData();
    const requst = axios.create({
      baseURL: "http://-----------:8000",
      timeout: 10000,
      headers: {
        "Content-Type": "multipart/form-data; boundary=wxmpFormBoundary",
      },
      adapter: TaroAdapter, // 添加这一行替换默认的适配器
    });

    const res = await requst.post("/api/v1/oss", convertData.buffer);
}

这样就可以正常上传了。

重点:

咱们这是自己伪造的FormData,虽然结果全部相等。但是也需要后端进行处理一下,不能直接使用,需要后端进行一下转换。

相关推荐
少恭写代码4 天前
duxapp 2024-12-18更新 新增 Svg 组件 Tab 支持幻灯片切换功能
react native·小程序·taro
苍岚丨晨苏5 天前
使用Taro开发iOS App触发额外权限请求的问题
react native·taro
码农爱java12 天前
Spring Boot 集成阿里云OSS 完成文件上传下载
spring boot·后端·阿里云·excel·oss·文件上传下载
sir.山16 天前
taro小程序进入腾讯验证码
小程序·taro·验证码·腾讯验证码·uniapp验证码·原生验证码
SuperherRo19 天前
基础入门-Web应用&OSS存储&负载均衡&CDN加速&反向代理&WAF防护&部署影响
负载均衡·cdn·oss·waf·基础入门
是陈哈哈噢19 天前
Taro小程序开发随记
前端·微信小程序·taro
他的猫哎20 天前
taro+vue3 + nut-popup微信小程序真机不显示问题
ios·微信小程序·vue·taro
他的猫哎20 天前
taro小程序马甲包插件
小程序·notepad++·taro
@ 前端小白21 天前
taro使用createAsyncThunk报错ReferenceError: AbortController is not defined
reactjs·taro
那就可爱多一点点1 个月前
在 Taro 中实现系统主题适配:亮/暗模式
taro