微信小程序:小程序常见问题及解决方案

原生组件显示在遮罩层上面的问题

在小程序中使用原生的表单组件时,在有弹出框出现的情况下,原生表单组件会出现在遮罩层上面,且会造成事件穿透的情况。

解决方案一:

使用cover-view,cover-view比原生组件的层级更高,或者说也是一种原生组件,不过在cover-view的子组件只能是coveri-view、cover-image,对于包含其他组件的弹框并不适用。

解决方案二:

使用page-container,page-container会弹出一个容器,可以承载任意组件。page-container原本是用来实现子页面的,不过用于实现弹框也是可以的。

由于是原本是用来显示子页面的所以在点击返回时可能会出现需要点击两次才会回退到上一个页面的情况,因此,需要自己手动回退一次。

至于事件穿透问题,在遮罩层上使用catch绑定tap、touchmove等事件阻止事件冒泡即可。

scroll-view高度适配问题

布局情况:
scroll-view的上面和下面的高度是固定的,scroll-view与下面部分之间有间隔,要在不同的机型下显示相同的间隔

  1. js解决
    使用windowHeight,减去固定部分的高度,剩余的高度为scroll-view的高度。固定部分的高度使用样式中的大小乘以不同机型的rpx的比率得到响应的px大小。

  2. css
    scroll-view的父元素设置为flex,absolute定位,设置top、bottom、left、right让父元素占据页面的剩余空间。底部元素也包含进scroll-view的父元素,设置固定高度和间隔。
    设置scroll-viewflex:1,让scroll-view占据父元素中的剩余空间。

表单控件聚焦后页面上推问题

现象:页面上滑导致自定义导航上滑
原因:1. 导航本身就没有加载完毕或者设置样式的时间在显示之后
2. 页面本身的上滑,带动了自定义导航的上滑
解决方法:1. 提前设置样式的时间,或者在多处设置样式2. 禁止页面上滑,使用wx.pageScrolTo({top:0}),在页面的配置文件中设置disableScroll:true。
3. 自定义实现页面上推逻辑,监听表单控件的聚焦事件,聚焦时更改元素的布局属性。

小程序web-view页面返回到小程序页面

背景:web-view中的支付页面,点击支付,跳转到小程序的支付页面,支付后返回到后端返回的web-view的url指定的页面,然后当用户点击返回时,从该页面返回到小程序首页。
解决思路:

  1. 使用popstate
    触发popstate的前提:

    1. 显式添加历史记录
    2. 监听popstate事件
    3. 用户交互:移动端为安卓机才需要,ios不需要

popstate在安卓上需要用户交互才能触发,但是项目又不能添加额外的交互,弃用popstate。

  1. 使用小程序页面栈进行返回
    思路:保证小程序在支付过程中页面栈中除tabbar页面外只有一个页面。当支付后从返回的页面返回到小程序的页面栈前一个页面,然后重定向到一个统一的页面,从该页面返回时目标页面的from为/,在beforeRouteEnter判断即可。

小程序上传文件超时

所用技术:

  • 前端:uniapp、vue3
  • 服务器:IIS、.net
    问题背景:微信小程序选择文件后,当用户点击提交按钮,调用wx.uploadFile上传文件,请求完毕后返回超时。
    解决方法
  1. 设置服务器的SSL配置,设置为忽略
  2. 使用wx.requestAPI,自己构造formData表单数据发送给后端

微信小程序构造表单数据依赖以下代码
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;

formData.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;
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端御书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值