一、场景
h5页面
实现一个上传组件,这个组件仅支持上传PDF, DOC, DOCX, JPG, JPEG, PNG, BMP, XLS, XLSX, CSV格式的文件
发版的前一天临近下班之际,测试提了一个bug,说安卓手机上传bmp文件提示格式错误,pc和ios都木有问题
丸辣,这不得真机调试,以前有用过LightProxy进行真机调试,但是新电脑还没有条件马上真机调试(接近下班了,懂的都懂 )
尽管到点了,还是安装了LightProxy,捣鼓了半小时,没代理成功,先放弃(有问题就告诉产品去掉这个类型的文件,又不是不能用.jpg)
二、真机调试条件准备
-
安装LightProxy
LightProxy官网
window直接下载
mac直接下载安装成功后:
-
关闭电脑防火墙
-
手机和电脑连上同一个WIFI
-
设置手机代理
长按已连接的WIFI-修改网络-代理选择手动,输入对应的代理地址
-
手机扫码下载证书
以华为手机为例:主屏幕滑到负一层,右上角有一个扫码入口,或者设置-账号点进去-右上角也有扫码入口
这里要确保证书已安装成功如何查看是否安装成功:
设置-安全-更多安全设置-加密和凭据-受信任的凭据-用户
若安装受限,例如提示 在"设置"中安装CA证书设置-安全-更多安全设置-加密和凭据-从存储设备安装-CA证书-任然安装-搜索root-安装已下载的rootAC证书即可
-
到这里手机尝试一下直接访问localhost:3000/xxx,发现未能正常进入页面,这时候需要进行第7步
-
设置ip映射:
-
到此,手机地址换成test.h5:3000/xxx,就可以正常访问了
三、项目添加vconsole
如果项目没有添加vconsole,手机没法查看console.log
所以添加一下vconsole
js
npm i vconsole -D
js
// 入口文件
import VConsole from 'vconsole';
if (process.env.NODE_ENV !== 'production') {
new VConsole();
}
添加之后,手机上就会出现绿色vConsole入口
四、发现问题
pc端:type为正常的image/bmp
安卓手机端:type并不是image/bmp
五、兼容处理bmp文件类型代码片段
js
import { invert } from "lodash";
export const MINE_TYPE = {
COMMON: "application/octet-stream",
PDF: "application/pdf",
DOC: "application/msword",
DOCX: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
XLS: "application/vnd.ms-excel",
XLSX: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
PNG: "image/png",
JPG: "image/jpeg",
GIF: "image/gif",
BMP: "image/bmp",
APK: "application/vnd.android.package-archive",
TXT: "text/plain",
HTML: "text/html",
CSV: "text/csv",
};
// 获取文件名后缀
const getFileSuffix = (filename: string) => {
const index = filename.lastIndexOf(".");
if (index !== -1) {
return filename.substr(index + 1);
}
return false;
};
/** 获取文件类型 - 即获取MINE_TYPE的key */
export const getFileType = (type: string) => {
return type.includes('bmp') ? 'BMP' : invert(MINE_TYPE)[type]
}
// 检查上传文件类型
export const checkTypes = (
file: RcFile,
typeList: string[],
forceSuffix: boolean = false
) => {
const type = typeList;
if (type && file && file.type && !forceSuffix) {
// 兼容安卓手機上傳bmp類型時,file.type !== image/bmp
if (type.includes(MINE_TYPE.BMP) && file.type.includes('bmp')) {
return true
}
return type.includes(file.type);
}
const suffix = getFileSuffix(file.name);
if (suffix && file && file.name) {
let pass = false;
const mine = invert(MINE_TYPE);
typeList.forEach((item) => {
if (!pass) {
pass = suffix.toLocaleUpperCase() === mine[item];
}
});
return pass;
}
return false;
};
js
// 拿到MINE_TYPE的key传给后端
const type = getFileType(file.type)
参考文章: