在微信原生小程序中,对于上传文件(图片,文件,语音,视频)都有自己的api最后使用wx.uploadFile上传到服务器。
wx.uploadFile 方式就不讲了 相信大家都会用,以下讲的是 fromdata 上传。
微信原生小程序中没有 fromdata对象,使用 new Fromdata() 会报错。
但是在很多需求中又会使用到 fromdata对象来保存到服务器中,就会用到以下两个文件。
注意:在需要使用 fromData 格式上传需要引入 两个文件,文件目录结构根据自己的需求构建。
1.新建一个 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;
2.新建 FromData.js 文件
import mimeMap from './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)=>{
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的charCode
endBoundaryArray.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 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;
};
export default FormData;
3.在需要使用 fromdata 的js文件夹中引入
// 引入
import FormData from '../../utils/formData.js'
// 使用
let from = new Fromdata()
formData.append("键名", "键值") // 一般参数
formData.appendFile("文件键名", 文件键值, "capture.webm") // 文件参数
let dataF = formData.getData(); //组合成data
// 发送请求
wx.request({ //请求函数
url: "", //接口地址
method: 'POST', // 请求方式
data: dataF.buffer, //数据字段
header: {
'content-type': dataF.contentType //请求头
},
success: (res) => {
console.log(res, '请求成功')
},
fail: function (error) {
console.log(error,'请求失败')
}
})
4.图片上传
chooseImage() {
wx.chooseMedia({
count: 9, // 可选择的图片数量
sizeType: ['compressed'], // 压缩图片
sourceType: ['album', 'camera'], // 来源:相册或相机
mediaType: ["image"], // 类型
success: (res) => {
let arr = []
// 得到的图片的地址
console.log(res.tempFiles, '图片');
this.setData({
imglist: [...this.data.imglist, ...arr]
})
}
})
},
// 再将得到的文件数组,或者单个的地址使用fromdata 型式上传
let from = new Fromdata()
formData.appendFile("文件键名", 文件键值, "capture.webm") // 文件参数
let dataF = formData.getData(); //组合成data
// 最后使用 wx.request()上传到服务器
4.1 图片预览
// 预览图片
previewImage: function (e) {
var current = e.currentTarget.dataset.src;
wx.previewImage({
current: current, // 当前显示图片的http链接
urls: this.data.imglist, // 需要预览的图片http链接数组
})
},
5.视频上传
// 开始录制视频
startVideo() {
let _this = this
wx.chooseMedia({
sourceType: ['album', 'camera'],//相机和相册
mediaType: ['video'],// 类型
maxDuration: 30, // 时间限制
camera: 'back',
success(res) {
//获取视频的大小(MB单位)
let size = parseFloat(res.tempFiles[0].size / 1024 / 1024).toFixed(1)
console.log(size, '视频大小');
if (size > 200) {
let beyongSize = size - 200 //获取视频超出限制大小的数量
Toast("上传的视频大小超限,超出" + beyongSize + "MB,请重新上传!")
return
}
console.log(res.tempFiles[0].tempFilePath, '视频成功的地址')
// 赋值地址
_this.setData({
videoSrc: res.tempFiles[0].tempFilePath
})
}
})
},
// 最后使用图片上传的 fromdata 型式封装数据,发送到服务器
6.录制语音上传
data的数据
curTime: 0,
timer: null,
secondes: 0,
startTimestamp: 0,
isupload: false
recorderManager: wx.getRecorderManager(),
// 语音录制函数
getRecordLimit() {
let that = this;
wx.getSetting({
success(res) {
if (!res.authSetting['scope.record']) { // 未授权
wx.authorize({
scope: 'scope.record',
success() { // 一次才成功授权
that._startRecord()
},
fail(err) {
console.log(err)
wx.showModal({
title: '温馨提示',
content: '您未授权录音,该功能将无法使用',
showCancel: true,
confirmText: "授权",
success: function (res) {
if (res.confirm) {
wx.openSetting({
success: (res) => {
if (!res.authSetting['scope.record']) {
//未设置录音授权
wx.showModal({
title: '提示',
content: '您未授权录音,功能将无法使用',
showCancel: false,
success: function () {}
})
} else { // 二次才成功授权
that._startRecord()
}
},
fail: function () {
console.log("授权设置录音失败");
}
})
}
},
fail: function (err) {
console.log("打开录音弹框失败 => ", err);
}
})
}
})
} else { // 已授权
that._startRecord()
}
}
})
},
_startRecord() {
this.data.startTimestamp = Date.now();
const options = {
duration: 300000, //指定录音的时长,单位 ms,最大为10分钟(600000),默认为1分钟(60000)
sampleRate: 16000, //采样率
numberOfChannels: 1, //录音通道数
encodeBitRate: 96000, //编码码率
format: 'mp3', //音频格式,有效值 aac/mp3
frameSize: 50, //指定帧大小,单位 KB
}
//点击录制
this.data.recorderManager.start(options);
//开始录音计时
this.countDown();
this.data.recorderManager.onStart(() => {
console.log('点击录制...')
})
//错误回调
this.data.recorderManager.onError((res) => {
console.log('录音失败', res);
})
},
_endRecord() {
clearInterval(this.data.timer);
this.data.recorderManager.stop();
this.data.recorderManager.onStop((res) => {
console.log('停止录音', res)
let filePath = res.tempFilePath;
let duration = res.duration;
this.setData({
audioUrl: filePath
})
if ((Date.now() - this.data.startTimestamp) / 1000 < 2) {
wx.showToast({
title: '录音时间太短!',
icon: 'none',
duration: 1500
})
return;
}
// 上传的接口
// this._uploadRecord(filePath, duration)
})
},
// 得到的录音时长
countDown() {
this.data.timer = setInterval(() => {
this.data.secondes++;
if (this.data.secondes > 360) {
clearInterval(this.data.timer);
this.data.recorderManager.stop();
this.data.recorderManager.onStop((res) => {
console.log('时辰已到,自动跳转')
let filePath = res.tempFilePath;
let duration = 360000;
this._uploadRecord(filePath, duration)
})
return;
}
this.setData({
curTime: this.data.secondes
});
}, 1000);
},
// 开始录音按钮
startRecording() {
this.setData({
issfksly: true,
isstartbtn: false,
curTime: 0,
secondes: 0,
issfbfly: true,
})
this.getRecordLimit()
return;
console.log('开始');
this.data.ctx.start({
duration: 600,
sampleRate: 16000, //采样率,有效值 8000/16000/44100
numberOfChannels: 1, //录音通道数,有效值 1/2
encodeBitRate: 96000, //编码码率
format: 'mp3', //音频格式,有效值 aac/mp3
frameSize: 50, //指定帧大小
audioSource: 'auto' //指定录音的音频输入源,可通过 wx.getAvailableAudioSources() 获取
})
},
// 结束录音按钮
endRecording() {
console.log("结束");
this._endRecord()
},
// 播放按钮
startbf: function () {
this.setData({
issfbfly: false,
isdisabled:true
})
// 获取innerAudioContext实例 == 注意 开始播放和停止播放需要用到同一个实例对象 wx.createInnerAudioContext()
this.setData({
innerAudioContext: wx.createInnerAudioContext()
})
// const innerAudioContext = wx.createInnerAudioContext()
// 是否自动播放
this.data.innerAudioContext.autoplay = true
// 设置音频文件的路径
this.data.innerAudioContext.src = this.data.audioUrl;
// 播放音频文件
this.data.innerAudioContext.onPlay(() => {
console.log('开始播放')
});
// 监听音频播放错误事件
this.data.innerAudioContext.onError((res) => {
console.log(res.errMsg)
console.log(res.errCode)
})
this.data.innerAudioContext.onEnded(()=>{
console.log("播放完了");
this.setData({
issfbfly: true,isdisabled:false
})
})
},
// 停止播放按钮
endbf() {
this.data.innerAudioContext.stop()
console.log("停止");
},
// 最后将得到的路径以 fromdata 形式上传到服务器
注意:静态显示需要自己写
以上就是 图片,语音录制播放,视频上传 的方法,写的不好请大家多多指教,觉得用的上 点个赞。