微信小程序上传图片组件,图片实现拖拽排序

  • 微信小程序上封装上传图片组件

  • 安装 weapp

  • components

  • components/imgUp/index.wxml



  • components/imgUp/index.json

    {
    "component": true,
    "usingComponents": {
    "van-cell": "@vant/weapp/cell/index",
    "HFilesImg": "../h-files-img/index"
    }
    }

  • components/imgUp/index.ts

    import { http } from "../../utils/api";

    Component({
    /**
    * 组件的属性列表
    */
    properties: {
    value: {
    type: Array,
    value: [],
    },
    type: {
    type: String,
    value: "",
    },
    Id: {
    type: String,
    value: "",
    },
    position: {
    type: String,
    value: "",
    },
    multiple: {
    type: Boolean,
    value: true,
    },
    deletable: {
    type: Boolean,
    value: true,
    },
    showUpload: {
    type: Boolean,
    value: true,
    },
    maxCount: {
    type: Number,
    value: 9,
    },
    uploadUrl: {
    type: String,
    value: "修改图片url地址",
    },
    deleteUrl: {
    type: String,
    value: "删除图片url地址",
    },
    gap: { type: Number, value: 9 },
    columns: { type: Number, value: 3 }, // // 列数
    previewSize: { type: Number, value: 100 }, // 图片大小
    deleteStyle: { type: String, value: "" },
    },

    /**
    * 组件的初始数据
    */
    data: {
    fileList: [],
    },
    lifetimes: {
    attached: function () {
    },
    },

    /**
    * 组件的方法列表
    /
    methods: {
    updateImageList(e: any) {
    console.log(e.detail);
    if (e.detail.length === 0) {
    return;
    } else {
    const list = e.detail.map((el: any, index: number) => ({
    id: el.id,
    order: index + 1,
    }));
    http({
    url: "NewHousing/MoveChange",
    method: "POST",
    data: {
    movechangelist: list,
    },
    }).then((res: any) => {
    if (res.errCode === 0) {
    console.log(res);
    }
    });
    }
    },
    // 文件读取完成
    onAfterRead(e: any) {
    e.detail.file.map((s: any) => {
    if (s.size > 4 * 1024 * 1024) {
    wx.showModal({
    content: "请上传小于4M的图片",
    showCancel: false,
    success: () => {},
    });
    } else {
    this.data.fileList.push({
    url: s.url,
    name: "图片" + this.data.fileList.length,
    state: 0, // 0:上传中 1:上传成功 2:上传失败
    fileId: null,
    });
    }
    });
    this.setData({
    fileList: this.data.fileList,
    });
    this.onAddFiles();
    },
    /
    * 附件上传 */
    onAddFiles() {
    let formDataObj: any = {};
    if (this.properties.Id) {
    formDataObj.id = this.properties.Id;
    }

    for (let index = 0; index < this.data.fileList.length; index++) {
    const el:any = this.data.fileList[index];
    wx.uploadFile({
    url: this.properties.Id ? this.properties.uploadUrl : '新增url地址',
    filePath: el.url,
    name: "file", //上传的所需字段,后端提供
    header: {
    Authorization: 'token值',
    },
    formData: formDataObj,
    success: (res: any) => {
    const data = JSON.parse(res.data);
    const arr: any[] = this.data.fileList.concat([]);
    arr[index]["id"] = data.data.id;
    arr[index]["url"] = data.data.filepath;
    arr[index]["state"] = 1;
    this.setData({ fileList: arr });
    this.triggerEvent("onChange", this.data.fileList);
    },
    fail: () => {
    const arr: any[] = this.data.fileList.concat([]);
    arr[index]["state"] = 2;
    this.setData({ fileList: arr });
    this.triggerEvent("onChange", this.data.fileList);
    },
    });
    }
    },

    // 点击删除文件
    onDelete(e: any) {
    if (this.properties.Id) {
    const that = this;
    wx.showModal({
    title: "提示",
    content: "确定要删除图片吗?",
    success(res) {
    if (res.confirm) {
    console.log("用户点击确定");
    const Id: any = that.properties.Id;
    const list: any = {
    id: Number(Id),
    attachid: e.detail.file.id, // 附件id
    };
    if (that.properties.type || that.properties.type === "0") {
    list.type = that.properties.type;
    }
    that.getDelete(list,that.properties.deleteUrl, e.detail.index);
    }
    },
    });
    } else {
    this.data.fileList.splice(e.detail.index, 1);
    this.setData({
    fileList: this.data.fileList,
    });
    this.triggerEvent("onChange", this.data.fileList);
    }
    },
    getDelete(list: any, url: any, index: any) {
    wx.showLoading({
    title: "loading...",
    });
    http({
    url: url,
    method: "POST",
    data: list,
    })
    .then((res: any) => {
    if (res.errCode === 0) {
    wx.showToast({
    title: "删除成功",
    icon: "success",
    });
    this.data.fileList.splice(index, 1);
    this.setData({
    fileList: this.data.fileList,
    });
    this.triggerEvent("onChange", this.data.fileList);
    }
    })
    .catch((err: any) => {
    const data = err.data;
    wx.showModal({
    title: "提示",
    showCancel: false,
    content: ${data.Message},
    });
    })
    .then(() => {
    wx.hideLoading();
    });
    },
    },
    observers: {
    value: function (value) {
    this.setData({
    fileList: value || [],
    });
    },
    },
    });

  • components/imgUp/index.scss

    .img-box {
    padding: 0 13px 13px;
    background-color: #fff;
    }

  • h-files-img 拖拽图片上传组件
  • components/h-files-img/index.wxml





    x




  • components/h-files-img/index.json

    {
    "component": true,
    "usingComponents": {
    "van-uploader": "@vant/weapp/uploader/index",
    "van-icon": "@vant/weapp/icon/index"
    }
    }

  • components/h-files-img/index.ts

    Component({
    options: { multipleSlots: !0 },
    properties: {
    showUpload: {
    type: Boolean,
    value: false,
    },
    previewSize: { type: Number, value: 100 }, // 图片大小
    fileList: { // 初始化图片数组
    type: Array,
    value: [],
    observer(t) {
    if (t?.length) {
    const e = this.getDragImgList(t);
    this.setUploaPosition(e.length),
    this.setData({ dragImgList: e })
    } else {
    this.setData({
    dragImgList: [],
    uploadPosition: {
    tranX: 0,
    tranY: 0,
    }
    })
    }
    }
    },
    deletable: {
    type: Boolean,
    value: false,
    },
    maxCount: { type: Number, value: 9 },// 图片上传数量限制
    columns: { type: Number, value: 3 }, // // 列数
    gap: { type: Number, value: 15 }, // // 图片间隔
    deleteStyle: { type: String, value: "" } // 删除样式
    },
    data: {
    dragImgList: [],
    containerRes: {
    top: 0, // 容器距离页面顶部距离 px
    left: 0, // 容器距离页面左边距离 px
    width: 100, // 容器宽度 px
    height: 100, // 容器高度 px
    }, // 拖拽容器属性
    currentKey: -1, // 正在拖拽图片的key
    currentIndex: -1, // 正在拖拽图片的index
    tranX: 0, // 正在拖拽图片移动的x距离
    tranY: 0, // 正在拖拽图片移动的y距离
    uploadPosition: { // upload上传图标位移距离
    tranX: 0,
    tranY: 0,
    },
    type: ''
    },
    lifetimes: {
    ready() {
    this.createSelectorQuery().select(".drag-container").boundingClientRect((({
    top: t, left: e }) => {
    this.setData({ "containerRes.top": t, "containerRes.left": e })
    })).exec()
    }
    },
    methods: {
    openImg(e: any) {
    const array = this.data.dragImgList.map((el:any) => el.url)
    wx.previewImage({
    current: e.currentTarget.dataset.url, // 当前显示图片的http链接
    urls: array // 需要预览的图片http链接列表
    })
    },
    /**
    * 长按图片
    /
    longPress(e: any) {
    const index = e.mark.index;
    const { pageX, pageY } = e.touches[0];
    const { previewSize, containerRes: { top, left } } = this.data;
    this.setData({
    currentIndex: index,
    tranX: pageX - previewSize / 2 - left,
    tranY: pageY - previewSize / 2 - top,
    type: 'move'
    });
    },
    /
    *
    * touchMove
    */
    touchMove(e: any) {
    // 如果currentIndex < 0,说明并没有触发longPress
    if (this.data.currentIndex < 0) {
    return;
    }
    const { pageX, pageY } = e.touches[0];
    const { previewSize, containerRes: { top, left } } = this.data;
    const tranX = pageX - previewSize / 2 - left;
    const tranY = pageY - previewSize / 2 - top;
    this.setData({
    tranX,
    tranY,
    type: 'move'
    });
    // 对比当前移动的key和停放位置的key,如果不一样就修改位置
    const currentKey = e.mark.key;
    const moveKey = this.getMoveKey(tranX, tranY);

    // 当移动的key和正在停放位置的key相等,就无须处理
    if (currentKey === moveKey || this.data.currentKey === currentKey) {
    return;
    }
    this.data.currentKey = currentKey;
    this.replace(currentKey, moveKey);
    },
    /**
    * 计算移动中的key
    * @param tranX 正在拖拽图片的tranX
    * @param tranY 正在拖拽图片的tranY
    /
    getMoveKey(tranX: number, tranY: number) {
    const { dragImgList: list, previewSize, columns } = this.data;
    const _getPositionNumber = (drag: any, limit: number) => {
    const positionNumber = Math.round(drag / previewSize);
    return positionNumber >= limit ? limit - 1 : positionNumber < 0 ? 0 : positionNumber;
    }
    const endKey = columns * _getPositionNumber(tranY, Math.ceil(list.length / columns)) + _getPositionNumber(tranX, columns);
    return endKey >= list.length ? list.length - 1 : endKey;
    },
    /
    *
    * 生成拖拽后的新数组
    * @param start 拖拽起始的key
    * @param end 拖拽结束的key
    /
    replace(start: number, end: number) {
    const dragImgList = this.data.dragImgList;
    dragImgList.forEach((item: any) => {
    if (start < end) {
    if (item.key > start && item.key <= end) item.key--;
    else if (item.key === start) item.key = end;
    } else if (start > end) {
    if (item.key >= end && item.key < start) item.key++;
    else if (item.key === start) item.key = end;
    }
    });
    this.getListPosition(dragImgList);
    },
    /
    *
    * 计算数组的位移位置
    * @param list 拖拽图片数组
    /
    getListPosition(list: any) {
    const { previewSize, columns, gap } = this.data;
    const dragImgList = list.map((item: any) => {
    item.tranX = (previewSize + gap) * (item.key % columns);
    item.tranY = Math.floor(item.key / columns) * (previewSize + gap);
    return item;
    })
    this.setData({
    dragImgList,
    });
    this.updateEvent(dragImgList);
    },
    /
    *
    * touchEnd
    /
    touchEnd() {
    this.setData({
    tranX: 0,
    tranY: 0,
    currentIndex: -1,
    type: 'move'
    });
    this.data.currentKey = -1;
    },
    /
    *
    * updateEvent
    * @describe 上传删除拖拽后触发事件把列表数据发给页面
    /
    updateEvent(dragImgList: any) {
    const list = [...dragImgList].sort((a, b) => a.key - b.key).map((item) => ({
    url: item.url,
    id: item.id
    }));
    this.triggerEvent('updateImageList', list);
    },
    /
    *
    * 上传图片
    /
    async uploadImage() {
    let { dragImgList, maxCount } = this.data;
    try {
    const res = await wx.chooseMedia({
    count: maxCount - dragImgList.length,
    mediaType: ['image'],
    });
    // 获取上传图片数据后需要初始化图片拽结构
    const imgList = this.getDragImgList(res?.tempFiles?.map(({ tempFilePath, size }) => ({ tempFilePath, size })) || [], false);
    dragImgList = dragImgList.concat(imgList);
    // 修改上传区域位置
    this.setUploaPosition(dragImgList.length);
    this.setData({
    dragImgList,
    type: ''
    });
    const list = {
    file: imgList
    }
    this.triggerEvent("onAfterRead", list);
    } catch (error) {
    console.log(error);
    }
    },
    /
    *
    * 改变图片数量后获取容器宽高
    * @parma listLength 数组长度
    /
    getContainerRect(listLength: number) {
    const { columns, previewSize, maxCount, gap } = this.data;
    const number = listLength === maxCount ? listLength : listLength + 1;
    const row = Math.ceil(number / columns)
    return {
    width: columns * previewSize + (columns - 1) * gap,
    height: row * previewSize + gap * (row - 1),
    };
    },
    /
    *
    * 根据图片列表生成拖拽列表数据结构
    * @param list 图片url列表
    * @param init 是否是初始化
    /
    getDragImgList(list: any, init = true) {
    let { dragImgList, previewSize, columns, gap } = this.data;
    return list.map((item: any, index: number) => {
    const i = (init ? 0 : dragImgList.length) + index;
    return {
    tranX: (previewSize + gap) * (i % columns),
    tranY: Math.floor(i / columns) * (previewSize + gap),
    url: item.tempFilePath ? item.tempFilePath : item.url,
    size: item.size || '',
    id: item.id ? item.id : null,
    key: i,
    };
    });
    },
    /
    *
    * 修改上传区域位置
    * @param listLength 数组长度
    /
    setUploaPosition(listLength: number) {
    const { previewSize, columns, gap } = this.data;
    const uploadPosition = {
    tranX: listLength % columns * (previewSize + gap),
    tranY: Math.floor(listLength / columns) * (previewSize + gap),
    };
    const { width, height } = this.getContainerRect(listLength);
    this.setData({
    uploadPosition,
    ['containerRes.width']: width,
    ['containerRes.height']: height,
    });
    },
    /
    *
    * 删除图片
    */
    deleteImg(e: any) {
    const key = e.mark.key;
    const obj = {
    file: e.currentTarget.dataset.item,
    index: key
    }
    this.triggerEvent("onDelete", obj);

    },

    }
    });

  • components/h-files-img/index.scss

    .drag-container {
    position: relative;
    }
    .drag-item {
    position: absolute;
    top: 0;
    left: 0;
    }
    .drag-item-transition {
    transition: transform 0.1s
    }
    .drag-item-img {
    width: 100%;
    height: 100%;
    }
    .drag-item-delete {
    position: absolute;
    top: 0;
    right: 0;
    touch-action: none;
    }
    .drag-item-delete_default {
    display: flex;
    width: 21px;
    height: 15px;
    line-height: 10px;
    justify-content: center;
    background-color: rgba(0, 0, 0, 0.7);
    border-radius: 0 0 0 12px;
    color: #FEFEFE;
    }
    .drag-upload .drag-upload_solt:empty+.drag-upload_default {
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    text-align: center;
    font-weight: bold;
    line-height: 100%;
    background-color: #f7f8fa;
    }
    .drag-upload .drag-upload_default {
    display: flex;
    align-items: center;
    justify-content: center;

    }

  • h-files-img 纯图片上传
  • components/h-files-img/index.wxml



  • components/h-files-img/index.json

    {
    "component": true,
    "usingComponents": { "van-uploader": "@vant/weapp/uploader/index" }
    }

  • components/h-files-img/index.ts

    Component({
    /**
    * 组件的属性列表
    */
    properties: {
    name: {
    type: String,
    value: "img",
    },
    fileList: {
    type: Array,
    value: [],
    },
    previewSize: {
    type: Number,
    value: 80,
    },
    multiple: {
    type: Boolean,
    value: true,
    },
    showUpload: {
    type: Boolean,
    value: false,
    },
    deletable: {
    type: Boolean,
    value: false,
    },
    maxCount: {
    type: Number,
    value: 9,
    },
    columnNum: {
    type: Number,
    value: 4,
    },
    },

    /**
    * 组件的初始数据
    */
    data: {
    width: 352,
    },

    lifetimes: {
    attached() {
    this.setData({
    width: (this.data.previewSize + 8) * this.data.columnNum,
    });
    },
    },

    /**
    * 组件的方法列表
    */
    methods: {
    // 文件读取完成后
    afterRead(event) {
    this.triggerEvent("onAfterRead", event.detail);
    },

    // 点击删除文件
    onDelete(e) {
    this.triggerEvent("onDelete", e.detail);
    },
    },
    });

  • pages

  • pages/index/index.wxml

  • pages/index/index.json

    {
    "navigationBarTitleText": "拖拽图片",
    "usingComponents": {
    "imgUp": "/components/imgUp/index"
    }
    }

  • pages/index/index.ts

    data: {
    imgList: []
    }

  • utils/api.ts

    import { getToken } from "./util";

    const baseUrl = "xx/api/"; // 后端接口
    export default baseUrl;
    export function http({ url = "", data = {}, method = "GET", header = {} }: IHttpOption = {}) {
    return new Promise(async (resolve: any, reject: any) => {
    const token = await getToken();
    hrefUrl = getBaseUrl(url)
    wx.request({
    url: hrefUrl,
    data: data,
    header: {
    Authorization: token ? ${token.type} ${token.token} : "",
    ...header,
    },
    method: method,
    complete: (res: any) => {
    if (res.statusCode >= 200 && res.statusCode < 300) {
    resolve(res.data);
    } else {
    const statusCode = res.statusCode;
    if (statusCode === 401) {
    wx.clearStorage();
    wx.showModal({
    title: "提示",
    content: "登录失效请重新登录",
    showCancel: false,
    success: function (res) {
    if (res.confirm) {
    wx.nextTick(() => {
    wx.navigateTo({
    url: "/pages/login/index",
    });
    });
    }
    },
    });
    } else if (statusCode === 404) {
    wx.showModal({
    title: "提示",
    content:"接口未发布请联系管理员",
    showCancel: false,
    });
    } else {
    reject(res);
    }
    }
    },
    });
    });
    }
    export function httpVisitors({ url = "", data = {}, method = "GET", header = {} }: IHttpOption = {}) {
    return new Promise(async (resolve: any, reject: any) => {
    wx.request({
    url: getBaseUrl(url),
    data: data,
    header: {
    ...header,
    },
    method: method,
    complete: (res: any) => {
    if (res.statusCode >= 200 && res.statusCode < 300) {
    resolve(res.data);
    } else {
    reject(res);
    }
    },
    });
    });
    }
    export function getBaseUrl(url: any) {
    if (url.indexOf("😕/") == -1) {
    url = baseUrl + url;
    }
    return url;
    }
    // get方法
    export function _get(url: any, data = {}) {
    return http({
    url,
    data,
    });
    }
    export function _post(url: any, data = {}) {
    return http({
    url,
    data,
    method: "POST",
    });
    }

  • 上传FormData格式

    import { httpVisitors } from "./api";
    const FormData = require('./formData.js')
    const formData = new FormData();
    formData.append('xxx', xxx);
    let data = formData.getData();
    httpVisitors({
    url: "",
    method: "POST",
    header: {
    'content-type': data.contentType,
    },
    data: data.buffer,
    })
    .then((res: any) => {})

  • utils/util.ts

    const FormData = require('./formData.js')
    /** 获取用户token */
    export async function getToken(username = '', password = '') {
    let token: any = _token;
    if (!token) {
    const tokenStr = wx.getStorageSync("token");
    if (tokenStr) {
    token = JSON.parse(tokenStr);
    }
    }
    if (token && Number(new Date()) < token.expires) {
    _token = token;
    return token;
    } else {
    wx.removeStorageSync("token");
    }
    const formData = new FormData();
    const name = username || wx.getStorageSync("loginName");
    const pass = password || wx.getStorageSync("loginPass");
    formData.append('username', name);
    formData.append('password', pass);
    formData.append('code', 2);
    let data = formData.getData();
    return await httpVisitors({
    url: "",
    method: "POST",
    header: {
    'content-type': data.contentType,
    },
    data: data.buffer,
    })
    .then((res: any) => {
    wx.hideLoading();
    if (res.errCode === -1) {
    wx.showModal({
    title: '提示',
    content: res.errMsg,
    showCancel: false,
    });
    return ''
    } else if (res.errCode === 0) {
    const data = res.data;
    const tokenJson = {
    type: 'bearer',
    token: data,
    expires: Number(new Date()) + 7200 * 1000,
    };
    _token = tokenJson;
    const tokenJsonStr = JSON.stringify(tokenJson);
    wx.setStorageSync("token", tokenJsonStr);
    return tokenJson;
    }
    })
    .catch(err => {
    const { statusCode } = err;
    if (statusCode === 404) {
    wx.hideLoading();
    wx.showModal({
    title: '提示',
    content: "接口未发布请联系管理员",
    showCancel: false,
    });
    } else {
    wx.hideLoading();
    return err;
    }
    });

    }

  • utils/formData.js

    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);
    if(Object.prototype.toString.call(buffer).indexOf("ArrayBuffer") < 0){
    return 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' + 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 = [];
    endBoundaryArray.push(...endBoundary.toUtf8Bytes());
    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 = [];
    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;

  • utils/mimeMap.js

    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",
    }

posted @ 2024-11-25 14:05  不完美的完美  阅读(535)  评论(0)    收藏  举报