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,虽然结果全部相等。但是也需要后端进行处理一下,不能直接使用,需要后端进行一下转换。

相关推荐
aiguangyuan2 天前
Taro 开发快速入门手册
taro·前端开发·移动端开发
aiguangyuan4 天前
Taro多端适配技术解析
taro·前端开发·移动端开发
Airser5 天前
npm启动Taro框架报错
前端·npm·taro
cococooder7 天前
阿里云 OSS postObject V4 使用
oss·aliyun·postobject
Dragon Wu8 天前
Taro 自定义tab栏和自定义导航栏
前端·javascript·小程序·typescript·前端框架·taro
菜鸟una13 天前
【微信小程序 + 消息订阅 + 授权】 微信小程序实现消息订阅流程介绍,代码示例(仅前端)
前端·vue.js·微信小程序·小程序·typescript·taro·1024程序员节
GISer_Jing23 天前
AI/CICD/Next/React Native&Taro内容
人工智能·react native·taro
OSS_ECAL23 天前
以下將介紹TLE493D-P2B6的概要,以及針對TLE493D-P2B6提供的OSS-ECAL
oss·嵌入式软件·i2c·电子元件·3d霍爾
GISer_Jing1 个月前
大前端——Taro、React-Native、Electron 大前端
前端·javascript·electron·taro
Thetimezipsby2 个月前
基于Taro4打造的一款最新版微信小程序、H5的多端开发简单模板
前端·javascript·微信小程序·typescript·html5·taro