[{"data":1,"prerenderedAt":2919},["ShallowReactive",2],{"docsNavigation":3,"blogNavigation":53,"/blog/file-upload-issue-solution":95,"/blog/file-upload-issue-solution-surround":2914},[4,38],{"title":5,"path":6,"stem":7,"children":8,"icon":37},"常用网站","/docs/getting-started","1.docs/1.getting-started/1.index",[9,12,17,22,27,32],{"title":10,"path":6,"stem":7,"icon":11},"区块链相关(前端)","i-lucide-box",{"title":13,"path":14,"stem":15,"icon":16},"图片压缩","/docs/getting-started/photo-compression","1.docs/1.getting-started/2.photo-compression","i-lucide-image",{"title":18,"path":19,"stem":20,"icon":21},"组件库","/docs/getting-started/component-library","1.docs/1.getting-started/3.component-library","i-lucide-puzzle",{"title":23,"path":24,"stem":25,"icon":26},"图表库","/docs/getting-started/charts","1.docs/1.getting-started/4.charts","i-lucide-bar-chart-3",{"title":28,"path":29,"stem":30,"icon":31},"CSS","/docs/getting-started/css","1.docs/1.getting-started/5.css","i-lucide-palette",{"title":33,"path":34,"stem":35,"icon":36},"调试测试工具","/docs/getting-started/test","1.docs/1.getting-started/6.test","i-lucide-bug",false,{"title":39,"path":40,"stem":41,"children":42,"page":37},"常用工具","/docs/essentials","1.docs/2.essentials",[43,48],{"title":44,"path":45,"stem":46,"icon":47},"uni-helper","/docs/essentials/uni-helper","1.docs/2.essentials/1.uni-helper","i-lucide-settings",{"title":49,"path":50,"stem":51,"icon":52},"工作流可视化库","/docs/essentials/workflow-libraries","1.docs/2.essentials/2.workflow-libraries","i-lucide-workflow",[54],{"title":55,"path":56,"stem":57,"children":58,"page":37},"Blog","/blog","3.blog",[59,63,67,71,75,79,83,87,91],{"title":60,"path":61,"stem":62},"Vue 3 中 \u003CTransition> 报错：组件根节点无法被动画化的解决方案","/blog/asian-cuisine","3.blog/1.asian-cuisine",{"title":64,"path":65,"stem":66},"使用 openapi-ts-request 自动生成 API 请求代码","/blog/apifox-api-generation","3.blog/2.apifox-api-generation",{"title":68,"path":69,"stem":70},"解决 uni.upload 多文件上传限制：使用 fetch + FormData 实现 H5 环境下的多文件上传","/blog/file-upload-issue-solution","3.blog/3.file-upload-issue-solution",{"title":72,"path":73,"stem":74},"Wangeditor中被div包裹的img标签被过滤问题解决方案","/blog/wangeditor-img-filter-issue","3.blog/4.wangeditor-img-filter-issue",{"title":76,"path":77,"stem":78},"Nuxt项目部署后报错 “Cannot load payload /_payload.json” 的修复","/blog/nuxt-payload-extraction","3.blog/5.nuxt-payload-extraction",{"title":80,"path":81,"stem":82},"Nuxt项目导入nuxt-echarts实现图表渲染","/blog/nuxt-echarts-implementation","3.blog/6.nuxt-echarts-implementation",{"title":84,"path":85,"stem":86},"Reown+Wagmi 在 UniApp+Vite 项目中的问题与解决方案","/blog/reown-wagmi-uniapp-issues","3.blog/7.reown-wagmi-uniapp-issues",{"title":88,"path":89,"stem":90},"数字滚动动画组件 - Vue 动画最佳实践","/blog/number-scroll-animation","3.blog/8.number-scroll-animation",{"title":92,"path":93,"stem":94},"新电脑安装 nvm 卡住？无需修改配置文件，一行命令完美解决！","/blog/nvm-install-solution","3.blog/9.nvm-install-solution",{"id":96,"title":68,"authors":97,"badge":102,"body":104,"date":2906,"description":2907,"extension":2908,"image":2909,"meta":2911,"navigation":380,"path":69,"seo":2912,"stem":70,"__hash__":2913},"posts/3.blog/3.file-upload-issue-solution.md",[98],{"name":99,"avatar":100},"qibmz",{"src":101},"/image/avatar.avif",{"label":103},"work",{"type":105,"value":106,"toc":2892},"minimark",[107,131,135,138,151,158,162,173,178,814,818,1891,1895,2776,2779,2783,2797,2801,2824,2828,2845,2848,2862,2879,2882,2888],[108,109,110,111,118,119,124,125,130],"p",{},"在使用 uni-app 开发过程中，我们经常 会遇到文件上传的需求。然而，",[112,113,117],"a",{"href":114,"rel":115},"https://uniapp.dcloud.net.cn/api/request/network-file.html#uploadfile",[116],"nofollow","uni.uploadFile"," 方法存在一个限制：它无法在一个请求中上传多个文件。本文将介绍如何在 H5 环境下使用 ",[112,120,123],{"href":121,"rel":122},"https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API",[116],"fetch"," + ",[112,126,129],{"href":127,"rel":128},"https://developer.mozilla.org/zh-CN/docs/Web/API/FormData",[116],"FormData"," 来解决这个问题。",[132,133,134],"h2",{"id":134},"问题描述",[108,136,137],{},"在开发中，我们常常需要一次性上传多个文件，例如：",[139,140,141,145,148],"ol",{},[142,143,144],"li",{},"上传多张图片作为产品展示",[142,146,147],{},"上传多个文档文件",[142,149,150],{},"同时上传头像和背景图",[108,152,153,154,157],{},"但是，uni-app 提供的 ",[112,155,117],{"href":114,"rel":156},[116]," API 只能上传单个文件，即使多次调用也可能导致后端处理复杂。",[132,159,161],{"id":160},"解决方案使用-fetch-formdata","解决方案：使用 fetch + FormData",[108,163,164,165,168,169,172],{},"在 H5 环境中，我们可以使用原生的 ",[112,166,123],{"href":121,"rel":167},[116]," 和 ",[112,170,129],{"href":127,"rel":171},[116]," 来实现多文件上传。",[174,175,177],"h3",{"id":176},"_1-基础实现","1. 基础实现",[179,180,185],"pre",{"className":181,"code":182,"language":183,"meta":184,"style":184},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","// 在 H5 环境下上传多文件\nfunction uploadMultipleFiles(files: File[], uploadUrl: string): Promise\u003Cany> {\n  // 检查是否在 H5 环境中\n  if ((globalThis as any).__PLATFORM__ !== 'h5') {\n    console.warn('此方法仅支持 H5 环境');\n    return Promise.reject(new Error('此方法仅支持 H5 环境'));\n  }\n\n  const formData = new FormData();\n  \n  // 将多个文件添加到 FormData 中\n  files.forEach((file: File, index: number) => {\n    // 可以使用相同字段名，后端会接收为数组\n    formData.append('files', file, file.name);\n    // 或者使用不同字段名\n    // formData.append(`file_${index}`, file, file.name);\n  });\n\n  // 添加其他参数\n  formData.append('userId', '123');\n  formData.append('category', 'images');\n\n  return fetch(uploadUrl, {\n    method: 'POST',\n    body: formData\n  })\n  .then(response => response.json()) // 注意：fetch 的 then 需先进行 json 处理\n  .then(data => {\n    console.log('上传成功:', data);\n    return data;\n  })\n  .catch(error => {\n    console.error('上传失败:', error);\n    throw error;\n  });\n}\n","ts","",[186,187,188,197,256,262,310,335,369,375,382,405,411,417,456,462,499,505,511,521,526,532,564,595,600,618,636,647,655,685,701,729,738,745,762,789,799,808],"code",{"__ignoreMap":184},[189,190,193],"span",{"class":191,"line":192},"line",1,[189,194,196],{"class":195},"sHwdD","// 在 H5 环境下上传多文件\n",[189,198,200,204,208,212,216,219,223,227,230,233,235,238,241,244,247,250,253],{"class":191,"line":199},2,[189,201,203],{"class":202},"spNyl","function",[189,205,207],{"class":206},"s2Zo4"," uploadMultipleFiles",[189,209,211],{"class":210},"sMK4o","(",[189,213,215],{"class":214},"sHdIc","files",[189,217,218],{"class":210},":",[189,220,222],{"class":221},"sBMFI"," File",[189,224,226],{"class":225},"sTEyZ","[]",[189,228,229],{"class":210},",",[189,231,232],{"class":214}," uploadUrl",[189,234,218],{"class":210},[189,236,237],{"class":221}," string",[189,239,240],{"class":210},"):",[189,242,243],{"class":221}," Promise",[189,245,246],{"class":210},"\u003C",[189,248,249],{"class":221},"any",[189,251,252],{"class":210},">",[189,254,255],{"class":210}," {\n",[189,257,259],{"class":191,"line":258},3,[189,260,261],{"class":195},"  // 检查是否在 H5 环境中\n",[189,263,265,269,273,276,279,282,285,288,291,294,297,301,304,307],{"class":191,"line":264},4,[189,266,268],{"class":267},"s7zQu","  if",[189,270,272],{"class":271},"swJcz"," ((",[189,274,275],{"class":225},"globalThis",[189,277,278],{"class":267}," as",[189,280,281],{"class":221}," any",[189,283,284],{"class":271},")",[189,286,287],{"class":210},".",[189,289,290],{"class":225},"__PLATFORM__",[189,292,293],{"class":210}," !==",[189,295,296],{"class":210}," '",[189,298,300],{"class":299},"sfazB","h5",[189,302,303],{"class":210},"'",[189,305,306],{"class":271},") ",[189,308,309],{"class":210},"{\n",[189,311,313,316,318,321,323,325,328,330,332],{"class":191,"line":312},5,[189,314,315],{"class":225},"    console",[189,317,287],{"class":210},[189,319,320],{"class":206},"warn",[189,322,211],{"class":271},[189,324,303],{"class":210},[189,326,327],{"class":299},"此方法仅支持 H5 环境",[189,329,303],{"class":210},[189,331,284],{"class":271},[189,333,334],{"class":210},";\n",[189,336,338,341,343,345,348,350,353,356,358,360,362,364,367],{"class":191,"line":337},6,[189,339,340],{"class":267},"    return",[189,342,243],{"class":221},[189,344,287],{"class":210},[189,346,347],{"class":206},"reject",[189,349,211],{"class":271},[189,351,352],{"class":210},"new",[189,354,355],{"class":206}," Error",[189,357,211],{"class":271},[189,359,303],{"class":210},[189,361,327],{"class":299},[189,363,303],{"class":210},[189,365,366],{"class":271},"))",[189,368,334],{"class":210},[189,370,372],{"class":191,"line":371},7,[189,373,374],{"class":210},"  }\n",[189,376,378],{"class":191,"line":377},8,[189,379,381],{"emptyLinePlaceholder":380},true,"\n",[189,383,385,388,391,394,397,400,403],{"class":191,"line":384},9,[189,386,387],{"class":202},"  const",[189,389,390],{"class":225}," formData",[189,392,393],{"class":210}," =",[189,395,396],{"class":210}," new",[189,398,399],{"class":206}," FormData",[189,401,402],{"class":271},"()",[189,404,334],{"class":210},[189,406,408],{"class":191,"line":407},10,[189,409,410],{"class":271},"  \n",[189,412,414],{"class":191,"line":413},11,[189,415,416],{"class":195},"  // 将多个文件添加到 FormData 中\n",[189,418,420,423,425,428,430,432,435,437,439,441,444,446,449,451,454],{"class":191,"line":419},12,[189,421,422],{"class":225},"  files",[189,424,287],{"class":210},[189,426,427],{"class":206},"forEach",[189,429,211],{"class":271},[189,431,211],{"class":210},[189,433,434],{"class":214},"file",[189,436,218],{"class":210},[189,438,222],{"class":221},[189,440,229],{"class":210},[189,442,443],{"class":214}," index",[189,445,218],{"class":210},[189,447,448],{"class":221}," number",[189,450,284],{"class":210},[189,452,453],{"class":202}," =>",[189,455,255],{"class":210},[189,457,459],{"class":191,"line":458},13,[189,460,461],{"class":195},"    // 可以使用相同字段名，后端会接收为数组\n",[189,463,465,468,470,473,475,477,479,481,483,486,488,490,492,495,497],{"class":191,"line":464},14,[189,466,467],{"class":225},"    formData",[189,469,287],{"class":210},[189,471,472],{"class":206},"append",[189,474,211],{"class":271},[189,476,303],{"class":210},[189,478,215],{"class":299},[189,480,303],{"class":210},[189,482,229],{"class":210},[189,484,485],{"class":225}," file",[189,487,229],{"class":210},[189,489,485],{"class":225},[189,491,287],{"class":210},[189,493,494],{"class":225},"name",[189,496,284],{"class":271},[189,498,334],{"class":210},[189,500,502],{"class":191,"line":501},15,[189,503,504],{"class":195},"    // 或者使用不同字段名\n",[189,506,508],{"class":191,"line":507},16,[189,509,510],{"class":195},"    // formData.append(`file_${index}`, file, file.name);\n",[189,512,514,517,519],{"class":191,"line":513},17,[189,515,516],{"class":210},"  }",[189,518,284],{"class":271},[189,520,334],{"class":210},[189,522,524],{"class":191,"line":523},18,[189,525,381],{"emptyLinePlaceholder":380},[189,527,529],{"class":191,"line":528},19,[189,530,531],{"class":195},"  // 添加其他参数\n",[189,533,535,538,540,542,544,546,549,551,553,555,558,560,562],{"class":191,"line":534},20,[189,536,537],{"class":225},"  formData",[189,539,287],{"class":210},[189,541,472],{"class":206},[189,543,211],{"class":271},[189,545,303],{"class":210},[189,547,548],{"class":299},"userId",[189,550,303],{"class":210},[189,552,229],{"class":210},[189,554,296],{"class":210},[189,556,557],{"class":299},"123",[189,559,303],{"class":210},[189,561,284],{"class":271},[189,563,334],{"class":210},[189,565,567,569,571,573,575,577,580,582,584,586,589,591,593],{"class":191,"line":566},21,[189,568,537],{"class":225},[189,570,287],{"class":210},[189,572,472],{"class":206},[189,574,211],{"class":271},[189,576,303],{"class":210},[189,578,579],{"class":299},"category",[189,581,303],{"class":210},[189,583,229],{"class":210},[189,585,296],{"class":210},[189,587,588],{"class":299},"images",[189,590,303],{"class":210},[189,592,284],{"class":271},[189,594,334],{"class":210},[189,596,598],{"class":191,"line":597},22,[189,599,381],{"emptyLinePlaceholder":380},[189,601,603,606,609,611,614,616],{"class":191,"line":602},23,[189,604,605],{"class":267},"  return",[189,607,608],{"class":206}," fetch",[189,610,211],{"class":271},[189,612,613],{"class":225},"uploadUrl",[189,615,229],{"class":210},[189,617,255],{"class":210},[189,619,621,624,626,628,631,633],{"class":191,"line":620},24,[189,622,623],{"class":271},"    method",[189,625,218],{"class":210},[189,627,296],{"class":210},[189,629,630],{"class":299},"POST",[189,632,303],{"class":210},[189,634,635],{"class":210},",\n",[189,637,639,642,644],{"class":191,"line":638},25,[189,640,641],{"class":271},"    body",[189,643,218],{"class":210},[189,645,646],{"class":225}," formData\n",[189,648,650,652],{"class":191,"line":649},26,[189,651,516],{"class":210},[189,653,654],{"class":271},")\n",[189,656,658,661,664,666,669,671,674,676,679,682],{"class":191,"line":657},27,[189,659,660],{"class":210},"  .",[189,662,663],{"class":206},"then",[189,665,211],{"class":271},[189,667,668],{"class":214},"response",[189,670,453],{"class":202},[189,672,673],{"class":225}," response",[189,675,287],{"class":210},[189,677,678],{"class":206},"json",[189,680,681],{"class":271},"()) ",[189,683,684],{"class":195},"// 注意：fetch 的 then 需先进行 json 处理\n",[189,686,688,690,692,694,697,699],{"class":191,"line":687},28,[189,689,660],{"class":210},[189,691,663],{"class":206},[189,693,211],{"class":271},[189,695,696],{"class":214},"data",[189,698,453],{"class":202},[189,700,255],{"class":210},[189,702,704,706,708,711,713,715,718,720,722,725,727],{"class":191,"line":703},29,[189,705,315],{"class":225},[189,707,287],{"class":210},[189,709,710],{"class":206},"log",[189,712,211],{"class":271},[189,714,303],{"class":210},[189,716,717],{"class":299},"上传成功:",[189,719,303],{"class":210},[189,721,229],{"class":210},[189,723,724],{"class":225}," data",[189,726,284],{"class":271},[189,728,334],{"class":210},[189,730,732,734,736],{"class":191,"line":731},30,[189,733,340],{"class":267},[189,735,724],{"class":225},[189,737,334],{"class":210},[189,739,741,743],{"class":191,"line":740},31,[189,742,516],{"class":210},[189,744,654],{"class":271},[189,746,748,750,753,755,758,760],{"class":191,"line":747},32,[189,749,660],{"class":210},[189,751,752],{"class":206},"catch",[189,754,211],{"class":271},[189,756,757],{"class":214},"error",[189,759,453],{"class":202},[189,761,255],{"class":210},[189,763,765,767,769,771,773,775,778,780,782,785,787],{"class":191,"line":764},33,[189,766,315],{"class":225},[189,768,287],{"class":210},[189,770,757],{"class":206},[189,772,211],{"class":271},[189,774,303],{"class":210},[189,776,777],{"class":299},"上传失败:",[189,779,303],{"class":210},[189,781,229],{"class":210},[189,783,784],{"class":225}," error",[189,786,284],{"class":271},[189,788,334],{"class":210},[189,790,792,795,797],{"class":191,"line":791},34,[189,793,794],{"class":267},"    throw",[189,796,784],{"class":225},[189,798,334],{"class":210},[189,800,802,804,806],{"class":191,"line":801},35,[189,803,516],{"class":210},[189,805,284],{"class":271},[189,807,334],{"class":210},[189,809,811],{"class":191,"line":810},36,[189,812,813],{"class":210},"}\n",[174,815,817],{"id":816},"_2-在-vue-组件中的使用示例","2. 在 Vue 组件中的使用示例",[179,819,823],{"className":820,"code":821,"language":822,"meta":184,"style":184},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Ctemplate>\n  \u003Cdiv class=\"upload-container\">\n    \u003Cinput \n      type=\"file\" \n      ref=\"fileInput\" \n      multiple \n      accept=\"image/*\" \n      @change=\"handleFileSelect\"\n    />\n    \u003Cbutton @click=\"uploadFiles\" :disabled=\"!selectedFiles.length\">\n      上传选中的 {{ selectedFiles.length }} 个文件\n    \u003C/button>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup>\nimport { ref } from 'vue';\n\nconst fileInput = ref(null);\nconst selectedFiles = ref([]);\n\nconst handleFileSelect = (event) => {\n  // 获取用户选择的文件列表\n  const files = Array.from(event.target.files);\n  selectedFiles.value = files;\n};\n\nconst uploadFiles = async () => {\n  if (!selectedFiles.value.length) {\n    alert('请先选择文件');\n    return;\n  }\n\n  // 检查是否在 H5 环境\n  if (process.client && typeof window !== 'undefined' && window.fetch) {\n    try {\n      const result = await uploadMultipleFiles(selectedFiles.value, '/api/upload');\n      console.log('上传结果:', result);\n      alert('上传成功');\n    } catch (error) {\n      console.error('上传失败:', error);\n      alert('上传失败: ' + error.message);\n    }\n  } else {\n    alert('此功能仅在 H5 环境下可用');\n  }\n};\n\n// 多文件上传函数\nasync function uploadMultipleFiles(files, uploadUrl) {\n  const formData = new FormData();\n  \n  // 将多个文件添加到 FormData 中\n  files.forEach(file => {\n    formData.append('files', file, file.name);\n  });\n\n  // 添加其他参数\n  formData.append('timestamp', Date.now().toString());\n\n  const response = await fetch(uploadUrl, {\n    method: 'POST',\n    body: formData\n  });\n\n  // 注意：fetch 的 then 需先进行 json 处理\n  if (response.ok) {\n    const result = await response.json();\n    return result;\n  } else {\n    throw new Error(`上传失败，状态码: ${response.status}`);\n  }\n}\n\u003C/script>\n","vue",[186,824,825,835,859,870,885,901,908,924,942,947,994,1016,1025,1034,1043,1047,1059,1084,1088,1109,1125,1129,1150,1155,1189,1205,1210,1214,1233,1255,1273,1279,1283,1287,1292,1336,1343,1380,1407,1426,1443,1468,1496,1502,1512,1530,1535,1540,1545,1551,1574,1591,1596,1601,1618,1651,1660,1665,1670,1710,1715,1736,1751,1760,1769,1774,1780,1798,1820,1829,1838,1872,1877,1882],{"__ignoreMap":184},[189,826,827,829,832],{"class":191,"line":192},[189,828,246],{"class":210},[189,830,831],{"class":271},"template",[189,833,834],{"class":210},">\n",[189,836,837,840,843,846,849,852,855,857],{"class":191,"line":199},[189,838,839],{"class":210},"  \u003C",[189,841,842],{"class":271},"div",[189,844,845],{"class":202}," class",[189,847,848],{"class":210},"=",[189,850,851],{"class":210},"\"",[189,853,854],{"class":299},"upload-container",[189,856,851],{"class":210},[189,858,834],{"class":210},[189,860,861,864,867],{"class":191,"line":258},[189,862,863],{"class":210},"    \u003C",[189,865,866],{"class":271},"input",[189,868,869],{"class":210}," \n",[189,871,872,875,877,879,881,883],{"class":191,"line":264},[189,873,874],{"class":202},"      type",[189,876,848],{"class":210},[189,878,851],{"class":210},[189,880,434],{"class":299},[189,882,851],{"class":210},[189,884,869],{"class":210},[189,886,887,890,892,894,897,899],{"class":191,"line":312},[189,888,889],{"class":202},"      ref",[189,891,848],{"class":210},[189,893,851],{"class":210},[189,895,896],{"class":299},"fileInput",[189,898,851],{"class":210},[189,900,869],{"class":210},[189,902,903,906],{"class":191,"line":337},[189,904,905],{"class":202},"      multiple",[189,907,869],{"class":210},[189,909,910,913,915,917,920,922],{"class":191,"line":371},[189,911,912],{"class":202},"      accept",[189,914,848],{"class":210},[189,916,851],{"class":210},[189,918,919],{"class":299},"image/*",[189,921,851],{"class":210},[189,923,869],{"class":210},[189,925,926,929,932,934,936,939],{"class":191,"line":377},[189,927,928],{"class":210},"      @",[189,930,931],{"class":202},"change",[189,933,848],{"class":210},[189,935,851],{"class":210},[189,937,938],{"class":225},"handleFileSelect",[189,940,941],{"class":210},"\"\n",[189,943,944],{"class":191,"line":384},[189,945,946],{"class":210},"    />\n",[189,948,949,951,954,957,960,962,964,967,969,972,975,977,979,982,985,987,990,992],{"class":191,"line":407},[189,950,863],{"class":210},[189,952,953],{"class":271},"button",[189,955,956],{"class":210}," @",[189,958,959],{"class":202},"click",[189,961,848],{"class":210},[189,963,851],{"class":210},[189,965,966],{"class":225},"uploadFiles",[189,968,851],{"class":210},[189,970,971],{"class":210}," :",[189,973,974],{"class":202},"disabled",[189,976,848],{"class":210},[189,978,851],{"class":210},[189,980,981],{"class":210},"!",[189,983,984],{"class":225},"selectedFiles",[189,986,287],{"class":210},[189,988,989],{"class":225},"length",[189,991,851],{"class":210},[189,993,834],{"class":210},[189,995,996,999,1002,1005,1007,1010,1013],{"class":191,"line":413},[189,997,998],{"class":225},"      上传选中的 ",[189,1000,1001],{"class":210},"{{",[189,1003,1004],{"class":225}," selectedFiles",[189,1006,287],{"class":210},[189,1008,1009],{"class":225},"length ",[189,1011,1012],{"class":210},"}}",[189,1014,1015],{"class":225}," 个文件\n",[189,1017,1018,1021,1023],{"class":191,"line":419},[189,1019,1020],{"class":210},"    \u003C/",[189,1022,953],{"class":271},[189,1024,834],{"class":210},[189,1026,1027,1030,1032],{"class":191,"line":458},[189,1028,1029],{"class":210},"  \u003C/",[189,1031,842],{"class":271},[189,1033,834],{"class":210},[189,1035,1036,1039,1041],{"class":191,"line":464},[189,1037,1038],{"class":210},"\u003C/",[189,1040,831],{"class":271},[189,1042,834],{"class":210},[189,1044,1045],{"class":191,"line":501},[189,1046,381],{"emptyLinePlaceholder":380},[189,1048,1049,1051,1054,1057],{"class":191,"line":507},[189,1050,246],{"class":210},[189,1052,1053],{"class":271},"script",[189,1055,1056],{"class":202}," setup",[189,1058,834],{"class":210},[189,1060,1061,1064,1067,1070,1073,1076,1078,1080,1082],{"class":191,"line":513},[189,1062,1063],{"class":267},"import",[189,1065,1066],{"class":210}," {",[189,1068,1069],{"class":225}," ref",[189,1071,1072],{"class":210}," }",[189,1074,1075],{"class":267}," from",[189,1077,296],{"class":210},[189,1079,822],{"class":299},[189,1081,303],{"class":210},[189,1083,334],{"class":210},[189,1085,1086],{"class":191,"line":523},[189,1087,381],{"emptyLinePlaceholder":380},[189,1089,1090,1093,1096,1098,1100,1102,1105,1107],{"class":191,"line":528},[189,1091,1092],{"class":202},"const",[189,1094,1095],{"class":225}," fileInput ",[189,1097,848],{"class":210},[189,1099,1069],{"class":206},[189,1101,211],{"class":225},[189,1103,1104],{"class":210},"null",[189,1106,284],{"class":225},[189,1108,334],{"class":210},[189,1110,1111,1113,1116,1118,1120,1123],{"class":191,"line":534},[189,1112,1092],{"class":202},[189,1114,1115],{"class":225}," selectedFiles ",[189,1117,848],{"class":210},[189,1119,1069],{"class":206},[189,1121,1122],{"class":225},"([])",[189,1124,334],{"class":210},[189,1126,1127],{"class":191,"line":566},[189,1128,381],{"emptyLinePlaceholder":380},[189,1130,1131,1133,1136,1138,1141,1144,1146,1148],{"class":191,"line":597},[189,1132,1092],{"class":202},[189,1134,1135],{"class":225}," handleFileSelect ",[189,1137,848],{"class":210},[189,1139,1140],{"class":210}," (",[189,1142,1143],{"class":214},"event",[189,1145,284],{"class":210},[189,1147,453],{"class":202},[189,1149,255],{"class":210},[189,1151,1152],{"class":191,"line":602},[189,1153,1154],{"class":195},"  // 获取用户选择的文件列表\n",[189,1156,1157,1159,1162,1164,1167,1169,1172,1174,1176,1178,1181,1183,1185,1187],{"class":191,"line":620},[189,1158,387],{"class":202},[189,1160,1161],{"class":225}," files",[189,1163,393],{"class":210},[189,1165,1166],{"class":225}," Array",[189,1168,287],{"class":210},[189,1170,1171],{"class":206},"from",[189,1173,211],{"class":271},[189,1175,1143],{"class":225},[189,1177,287],{"class":210},[189,1179,1180],{"class":225},"target",[189,1182,287],{"class":210},[189,1184,215],{"class":225},[189,1186,284],{"class":271},[189,1188,334],{"class":210},[189,1190,1191,1194,1196,1199,1201,1203],{"class":191,"line":638},[189,1192,1193],{"class":225},"  selectedFiles",[189,1195,287],{"class":210},[189,1197,1198],{"class":225},"value",[189,1200,393],{"class":210},[189,1202,1161],{"class":225},[189,1204,334],{"class":210},[189,1206,1207],{"class":191,"line":649},[189,1208,1209],{"class":210},"};\n",[189,1211,1212],{"class":191,"line":657},[189,1213,381],{"emptyLinePlaceholder":380},[189,1215,1216,1218,1221,1223,1226,1229,1231],{"class":191,"line":687},[189,1217,1092],{"class":202},[189,1219,1220],{"class":225}," uploadFiles ",[189,1222,848],{"class":210},[189,1224,1225],{"class":202}," async",[189,1227,1228],{"class":210}," ()",[189,1230,453],{"class":202},[189,1232,255],{"class":210},[189,1234,1235,1237,1239,1241,1243,1245,1247,1249,1251,1253],{"class":191,"line":703},[189,1236,268],{"class":267},[189,1238,1140],{"class":271},[189,1240,981],{"class":210},[189,1242,984],{"class":225},[189,1244,287],{"class":210},[189,1246,1198],{"class":225},[189,1248,287],{"class":210},[189,1250,989],{"class":225},[189,1252,306],{"class":271},[189,1254,309],{"class":210},[189,1256,1257,1260,1262,1264,1267,1269,1271],{"class":191,"line":731},[189,1258,1259],{"class":206},"    alert",[189,1261,211],{"class":271},[189,1263,303],{"class":210},[189,1265,1266],{"class":299},"请先选择文件",[189,1268,303],{"class":210},[189,1270,284],{"class":271},[189,1272,334],{"class":210},[189,1274,1275,1277],{"class":191,"line":740},[189,1276,340],{"class":267},[189,1278,334],{"class":210},[189,1280,1281],{"class":191,"line":747},[189,1282,374],{"class":210},[189,1284,1285],{"class":191,"line":764},[189,1286,381],{"emptyLinePlaceholder":380},[189,1288,1289],{"class":191,"line":791},[189,1290,1291],{"class":195},"  // 检查是否在 H5 环境\n",[189,1293,1294,1296,1298,1301,1303,1306,1309,1312,1315,1317,1319,1322,1324,1326,1328,1330,1332,1334],{"class":191,"line":801},[189,1295,268],{"class":267},[189,1297,1140],{"class":271},[189,1299,1300],{"class":225},"process",[189,1302,287],{"class":210},[189,1304,1305],{"class":225},"client",[189,1307,1308],{"class":210}," &&",[189,1310,1311],{"class":210}," typeof",[189,1313,1314],{"class":225}," window",[189,1316,293],{"class":210},[189,1318,296],{"class":210},[189,1320,1321],{"class":299},"undefined",[189,1323,303],{"class":210},[189,1325,1308],{"class":210},[189,1327,1314],{"class":225},[189,1329,287],{"class":210},[189,1331,123],{"class":225},[189,1333,306],{"class":271},[189,1335,309],{"class":210},[189,1337,1338,1341],{"class":191,"line":810},[189,1339,1340],{"class":267},"    try",[189,1342,255],{"class":210},[189,1344,1346,1349,1352,1354,1357,1359,1361,1363,1365,1367,1369,1371,1374,1376,1378],{"class":191,"line":1345},37,[189,1347,1348],{"class":202},"      const",[189,1350,1351],{"class":225}," result",[189,1353,393],{"class":210},[189,1355,1356],{"class":267}," await",[189,1358,207],{"class":206},[189,1360,211],{"class":271},[189,1362,984],{"class":225},[189,1364,287],{"class":210},[189,1366,1198],{"class":225},[189,1368,229],{"class":210},[189,1370,296],{"class":210},[189,1372,1373],{"class":299},"/api/upload",[189,1375,303],{"class":210},[189,1377,284],{"class":271},[189,1379,334],{"class":210},[189,1381,1383,1386,1388,1390,1392,1394,1397,1399,1401,1403,1405],{"class":191,"line":1382},38,[189,1384,1385],{"class":225},"      console",[189,1387,287],{"class":210},[189,1389,710],{"class":206},[189,1391,211],{"class":271},[189,1393,303],{"class":210},[189,1395,1396],{"class":299},"上传结果:",[189,1398,303],{"class":210},[189,1400,229],{"class":210},[189,1402,1351],{"class":225},[189,1404,284],{"class":271},[189,1406,334],{"class":210},[189,1408,1410,1413,1415,1417,1420,1422,1424],{"class":191,"line":1409},39,[189,1411,1412],{"class":206},"      alert",[189,1414,211],{"class":271},[189,1416,303],{"class":210},[189,1418,1419],{"class":299},"上传成功",[189,1421,303],{"class":210},[189,1423,284],{"class":271},[189,1425,334],{"class":210},[189,1427,1429,1432,1435,1437,1439,1441],{"class":191,"line":1428},40,[189,1430,1431],{"class":210},"    }",[189,1433,1434],{"class":267}," catch",[189,1436,1140],{"class":271},[189,1438,757],{"class":225},[189,1440,306],{"class":271},[189,1442,309],{"class":210},[189,1444,1446,1448,1450,1452,1454,1456,1458,1460,1462,1464,1466],{"class":191,"line":1445},41,[189,1447,1385],{"class":225},[189,1449,287],{"class":210},[189,1451,757],{"class":206},[189,1453,211],{"class":271},[189,1455,303],{"class":210},[189,1457,777],{"class":299},[189,1459,303],{"class":210},[189,1461,229],{"class":210},[189,1463,784],{"class":225},[189,1465,284],{"class":271},[189,1467,334],{"class":210},[189,1469,1471,1473,1475,1477,1480,1482,1485,1487,1489,1492,1494],{"class":191,"line":1470},42,[189,1472,1412],{"class":206},[189,1474,211],{"class":271},[189,1476,303],{"class":210},[189,1478,1479],{"class":299},"上传失败: ",[189,1481,303],{"class":210},[189,1483,1484],{"class":210}," +",[189,1486,784],{"class":225},[189,1488,287],{"class":210},[189,1490,1491],{"class":225},"message",[189,1493,284],{"class":271},[189,1495,334],{"class":210},[189,1497,1499],{"class":191,"line":1498},43,[189,1500,1501],{"class":210},"    }\n",[189,1503,1505,1507,1510],{"class":191,"line":1504},44,[189,1506,516],{"class":210},[189,1508,1509],{"class":267}," else",[189,1511,255],{"class":210},[189,1513,1515,1517,1519,1521,1524,1526,1528],{"class":191,"line":1514},45,[189,1516,1259],{"class":206},[189,1518,211],{"class":271},[189,1520,303],{"class":210},[189,1522,1523],{"class":299},"此功能仅在 H5 环境下可用",[189,1525,303],{"class":210},[189,1527,284],{"class":271},[189,1529,334],{"class":210},[189,1531,1533],{"class":191,"line":1532},46,[189,1534,374],{"class":210},[189,1536,1538],{"class":191,"line":1537},47,[189,1539,1209],{"class":210},[189,1541,1543],{"class":191,"line":1542},48,[189,1544,381],{"emptyLinePlaceholder":380},[189,1546,1548],{"class":191,"line":1547},49,[189,1549,1550],{"class":195},"// 多文件上传函数\n",[189,1552,1554,1557,1560,1562,1564,1566,1568,1570,1572],{"class":191,"line":1553},50,[189,1555,1556],{"class":202},"async",[189,1558,1559],{"class":202}," function",[189,1561,207],{"class":206},[189,1563,211],{"class":210},[189,1565,215],{"class":214},[189,1567,229],{"class":210},[189,1569,232],{"class":214},[189,1571,284],{"class":210},[189,1573,255],{"class":210},[189,1575,1577,1579,1581,1583,1585,1587,1589],{"class":191,"line":1576},51,[189,1578,387],{"class":202},[189,1580,390],{"class":225},[189,1582,393],{"class":210},[189,1584,396],{"class":210},[189,1586,399],{"class":206},[189,1588,402],{"class":271},[189,1590,334],{"class":210},[189,1592,1594],{"class":191,"line":1593},52,[189,1595,410],{"class":271},[189,1597,1599],{"class":191,"line":1598},53,[189,1600,416],{"class":195},[189,1602,1604,1606,1608,1610,1612,1614,1616],{"class":191,"line":1603},54,[189,1605,422],{"class":225},[189,1607,287],{"class":210},[189,1609,427],{"class":206},[189,1611,211],{"class":271},[189,1613,434],{"class":214},[189,1615,453],{"class":202},[189,1617,255],{"class":210},[189,1619,1621,1623,1625,1627,1629,1631,1633,1635,1637,1639,1641,1643,1645,1647,1649],{"class":191,"line":1620},55,[189,1622,467],{"class":225},[189,1624,287],{"class":210},[189,1626,472],{"class":206},[189,1628,211],{"class":271},[189,1630,303],{"class":210},[189,1632,215],{"class":299},[189,1634,303],{"class":210},[189,1636,229],{"class":210},[189,1638,485],{"class":225},[189,1640,229],{"class":210},[189,1642,485],{"class":225},[189,1644,287],{"class":210},[189,1646,494],{"class":225},[189,1648,284],{"class":271},[189,1650,334],{"class":210},[189,1652,1654,1656,1658],{"class":191,"line":1653},56,[189,1655,516],{"class":210},[189,1657,284],{"class":271},[189,1659,334],{"class":210},[189,1661,1663],{"class":191,"line":1662},57,[189,1664,381],{"emptyLinePlaceholder":380},[189,1666,1668],{"class":191,"line":1667},58,[189,1669,531],{"class":195},[189,1671,1673,1675,1677,1679,1681,1683,1686,1688,1690,1693,1695,1698,1700,1702,1705,1708],{"class":191,"line":1672},59,[189,1674,537],{"class":225},[189,1676,287],{"class":210},[189,1678,472],{"class":206},[189,1680,211],{"class":271},[189,1682,303],{"class":210},[189,1684,1685],{"class":299},"timestamp",[189,1687,303],{"class":210},[189,1689,229],{"class":210},[189,1691,1692],{"class":225}," Date",[189,1694,287],{"class":210},[189,1696,1697],{"class":206},"now",[189,1699,402],{"class":271},[189,1701,287],{"class":210},[189,1703,1704],{"class":206},"toString",[189,1706,1707],{"class":271},"())",[189,1709,334],{"class":210},[189,1711,1713],{"class":191,"line":1712},60,[189,1714,381],{"emptyLinePlaceholder":380},[189,1716,1718,1720,1722,1724,1726,1728,1730,1732,1734],{"class":191,"line":1717},61,[189,1719,387],{"class":202},[189,1721,673],{"class":225},[189,1723,393],{"class":210},[189,1725,1356],{"class":267},[189,1727,608],{"class":206},[189,1729,211],{"class":271},[189,1731,613],{"class":225},[189,1733,229],{"class":210},[189,1735,255],{"class":210},[189,1737,1739,1741,1743,1745,1747,1749],{"class":191,"line":1738},62,[189,1740,623],{"class":271},[189,1742,218],{"class":210},[189,1744,296],{"class":210},[189,1746,630],{"class":299},[189,1748,303],{"class":210},[189,1750,635],{"class":210},[189,1752,1754,1756,1758],{"class":191,"line":1753},63,[189,1755,641],{"class":271},[189,1757,218],{"class":210},[189,1759,646],{"class":225},[189,1761,1763,1765,1767],{"class":191,"line":1762},64,[189,1764,516],{"class":210},[189,1766,284],{"class":271},[189,1768,334],{"class":210},[189,1770,1772],{"class":191,"line":1771},65,[189,1773,381],{"emptyLinePlaceholder":380},[189,1775,1777],{"class":191,"line":1776},66,[189,1778,1779],{"class":195},"  // 注意：fetch 的 then 需先进行 json 处理\n",[189,1781,1783,1785,1787,1789,1791,1794,1796],{"class":191,"line":1782},67,[189,1784,268],{"class":267},[189,1786,1140],{"class":271},[189,1788,668],{"class":225},[189,1790,287],{"class":210},[189,1792,1793],{"class":225},"ok",[189,1795,306],{"class":271},[189,1797,309],{"class":210},[189,1799,1801,1804,1806,1808,1810,1812,1814,1816,1818],{"class":191,"line":1800},68,[189,1802,1803],{"class":202},"    const",[189,1805,1351],{"class":225},[189,1807,393],{"class":210},[189,1809,1356],{"class":267},[189,1811,673],{"class":225},[189,1813,287],{"class":210},[189,1815,678],{"class":206},[189,1817,402],{"class":271},[189,1819,334],{"class":210},[189,1821,1823,1825,1827],{"class":191,"line":1822},69,[189,1824,340],{"class":267},[189,1826,1351],{"class":225},[189,1828,334],{"class":210},[189,1830,1832,1834,1836],{"class":191,"line":1831},70,[189,1833,516],{"class":210},[189,1835,1509],{"class":267},[189,1837,255],{"class":210},[189,1839,1841,1843,1845,1847,1849,1852,1855,1858,1860,1862,1865,1868,1870],{"class":191,"line":1840},71,[189,1842,794],{"class":267},[189,1844,396],{"class":210},[189,1846,355],{"class":206},[189,1848,211],{"class":271},[189,1850,1851],{"class":210},"`",[189,1853,1854],{"class":299},"上传失败，状态码: ",[189,1856,1857],{"class":210},"${",[189,1859,668],{"class":225},[189,1861,287],{"class":210},[189,1863,1864],{"class":225},"status",[189,1866,1867],{"class":210},"}`",[189,1869,284],{"class":271},[189,1871,334],{"class":210},[189,1873,1875],{"class":191,"line":1874},72,[189,1876,374],{"class":210},[189,1878,1880],{"class":191,"line":1879},73,[189,1881,813],{"class":210},[189,1883,1885,1887,1889],{"class":191,"line":1884},74,[189,1886,1038],{"class":210},[189,1888,1053],{"class":271},[189,1890,834],{"class":210},[174,1892,1894],{"id":1893},"_3-处理上传进度","3. 处理上传进度",[179,1896,1900],{"className":1897,"code":1898,"language":1899,"meta":184,"style":184},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","// 带进度的上传实现\ninterface UploadProgressCallback {\n  (progress: number): void;\n}\n\ninterface FileUploadResponse {\n  [key: string]: any; // 根据实际后端响应类型调整\n}\n\nfunction uploadMultipleFilesWithProgress(\n  files: File[], \n  uploadUrl: string, \n  onProgress?: UploadProgressCallback\n): Promise\u003CFileUploadResponse> {\n  return new Promise((resolve, reject) => {\n    if ((globalThis as any).__PLATFORM__ !== 'h5') {\n      reject(new Error('此方法仅支持 H5 环境'));\n      return;\n    }\n\n    const formData = new FormData();\n    \n    files.forEach(file => {\n      formData.append('files', file, file.name);\n    });\n\n    const xhr = new XMLHttpRequest();\n\n    // 监听上传进度\n    xhr.upload.addEventListener('progress', (event: ProgressEvent) => {\n      if (event.lengthComputable) {\n        const percentComplete = (event.loaded / event.total) * 100;\n        onProgress && onProgress(percentComplete);\n      }\n    });\n\n    xhr.addEventListener('load', () => {\n      if (xhr.status >= 200 && xhr.status \u003C 300) {\n        try {\n          const result = JSON.parse(xhr.response);\n          resolve(result);\n        } catch (error) {\n          reject(new Error('响应解析失败'));\n        }\n      } else {\n        reject(new Error(`上传失败: ${xhr.statusText}`));\n      }\n    });\n\n    xhr.addEventListener('error', () => {\n      reject(new Error('网络错误'));\n    });\n\n    xhr.addEventListener('abort', () => {\n      reject(new Error('上传被取消'));\n    });\n\n    xhr.open('POST', uploadUrl);\n    xhr.send(formData);\n  });\n}\n","js",[186,1901,1902,1907,1917,1936,1940,1944,1953,1978,1982,1986,1996,2010,2023,2034,2049,2075,2106,2129,2136,2140,2144,2160,2165,2182,2215,2223,2227,2245,2249,2254,2294,2312,2353,2372,2377,2385,2389,2414,2451,2458,2487,2501,2516,2540,2545,2554,2586,2590,2598,2602,2626,2649,2657,2661,2686,2709,2717,2721,2746,2764,2772],{"__ignoreMap":184},[189,1903,1904],{"class":191,"line":192},[189,1905,1906],{"class":195},"// 带进度的上传实现\n",[189,1908,1909,1912,1915],{"class":191,"line":199},[189,1910,1911],{"class":202},"interface",[189,1913,1914],{"class":221}," UploadProgressCallback",[189,1916,255],{"class":210},[189,1918,1919,1922,1925,1927,1929,1931,1934],{"class":191,"line":258},[189,1920,1921],{"class":210},"  (",[189,1923,1924],{"class":214},"progress",[189,1926,218],{"class":210},[189,1928,448],{"class":221},[189,1930,240],{"class":210},[189,1932,1933],{"class":221}," void",[189,1935,334],{"class":210},[189,1937,1938],{"class":191,"line":264},[189,1939,813],{"class":210},[189,1941,1942],{"class":191,"line":312},[189,1943,381],{"emptyLinePlaceholder":380},[189,1945,1946,1948,1951],{"class":191,"line":337},[189,1947,1911],{"class":202},[189,1949,1950],{"class":221}," FileUploadResponse",[189,1952,255],{"class":210},[189,1954,1955,1958,1961,1963,1965,1968,1970,1972,1975],{"class":191,"line":371},[189,1956,1957],{"class":225},"  [",[189,1959,1960],{"class":214},"key",[189,1962,218],{"class":210},[189,1964,237],{"class":221},[189,1966,1967],{"class":225},"]",[189,1969,218],{"class":210},[189,1971,281],{"class":221},[189,1973,1974],{"class":210},";",[189,1976,1977],{"class":195}," // 根据实际后端响应类型调整\n",[189,1979,1980],{"class":191,"line":377},[189,1981,813],{"class":210},[189,1983,1984],{"class":191,"line":384},[189,1985,381],{"emptyLinePlaceholder":380},[189,1987,1988,1990,1993],{"class":191,"line":407},[189,1989,203],{"class":202},[189,1991,1992],{"class":206}," uploadMultipleFilesWithProgress",[189,1994,1995],{"class":210},"(\n",[189,1997,1998,2000,2002,2004,2006,2008],{"class":191,"line":413},[189,1999,422],{"class":214},[189,2001,218],{"class":210},[189,2003,222],{"class":221},[189,2005,226],{"class":225},[189,2007,229],{"class":210},[189,2009,869],{"class":225},[189,2011,2012,2015,2017,2019,2021],{"class":191,"line":419},[189,2013,2014],{"class":214},"  uploadUrl",[189,2016,218],{"class":210},[189,2018,237],{"class":221},[189,2020,229],{"class":210},[189,2022,869],{"class":225},[189,2024,2025,2028,2031],{"class":191,"line":458},[189,2026,2027],{"class":214},"  onProgress",[189,2029,2030],{"class":210},"?:",[189,2032,2033],{"class":221}," UploadProgressCallback\n",[189,2035,2036,2038,2040,2042,2045,2047],{"class":191,"line":464},[189,2037,240],{"class":210},[189,2039,243],{"class":221},[189,2041,246],{"class":210},[189,2043,2044],{"class":221},"FileUploadResponse",[189,2046,252],{"class":210},[189,2048,255],{"class":210},[189,2050,2051,2053,2055,2057,2059,2061,2064,2066,2069,2071,2073],{"class":191,"line":501},[189,2052,605],{"class":267},[189,2054,396],{"class":210},[189,2056,243],{"class":221},[189,2058,211],{"class":271},[189,2060,211],{"class":210},[189,2062,2063],{"class":214},"resolve",[189,2065,229],{"class":210},[189,2067,2068],{"class":214}," reject",[189,2070,284],{"class":210},[189,2072,453],{"class":202},[189,2074,255],{"class":210},[189,2076,2077,2080,2082,2084,2086,2088,2090,2092,2094,2096,2098,2100,2102,2104],{"class":191,"line":507},[189,2078,2079],{"class":267},"    if",[189,2081,272],{"class":271},[189,2083,275],{"class":225},[189,2085,278],{"class":267},[189,2087,281],{"class":221},[189,2089,284],{"class":271},[189,2091,287],{"class":210},[189,2093,290],{"class":225},[189,2095,293],{"class":210},[189,2097,296],{"class":210},[189,2099,300],{"class":299},[189,2101,303],{"class":210},[189,2103,306],{"class":271},[189,2105,309],{"class":210},[189,2107,2108,2111,2113,2115,2117,2119,2121,2123,2125,2127],{"class":191,"line":513},[189,2109,2110],{"class":206},"      reject",[189,2112,211],{"class":271},[189,2114,352],{"class":210},[189,2116,355],{"class":206},[189,2118,211],{"class":271},[189,2120,303],{"class":210},[189,2122,327],{"class":299},[189,2124,303],{"class":210},[189,2126,366],{"class":271},[189,2128,334],{"class":210},[189,2130,2131,2134],{"class":191,"line":523},[189,2132,2133],{"class":267},"      return",[189,2135,334],{"class":210},[189,2137,2138],{"class":191,"line":528},[189,2139,1501],{"class":210},[189,2141,2142],{"class":191,"line":534},[189,2143,381],{"emptyLinePlaceholder":380},[189,2145,2146,2148,2150,2152,2154,2156,2158],{"class":191,"line":566},[189,2147,1803],{"class":202},[189,2149,390],{"class":225},[189,2151,393],{"class":210},[189,2153,396],{"class":210},[189,2155,399],{"class":206},[189,2157,402],{"class":271},[189,2159,334],{"class":210},[189,2161,2162],{"class":191,"line":597},[189,2163,2164],{"class":271},"    \n",[189,2166,2167,2170,2172,2174,2176,2178,2180],{"class":191,"line":602},[189,2168,2169],{"class":225},"    files",[189,2171,287],{"class":210},[189,2173,427],{"class":206},[189,2175,211],{"class":271},[189,2177,434],{"class":214},[189,2179,453],{"class":202},[189,2181,255],{"class":210},[189,2183,2184,2187,2189,2191,2193,2195,2197,2199,2201,2203,2205,2207,2209,2211,2213],{"class":191,"line":620},[189,2185,2186],{"class":225},"      formData",[189,2188,287],{"class":210},[189,2190,472],{"class":206},[189,2192,211],{"class":271},[189,2194,303],{"class":210},[189,2196,215],{"class":299},[189,2198,303],{"class":210},[189,2200,229],{"class":210},[189,2202,485],{"class":225},[189,2204,229],{"class":210},[189,2206,485],{"class":225},[189,2208,287],{"class":210},[189,2210,494],{"class":225},[189,2212,284],{"class":271},[189,2214,334],{"class":210},[189,2216,2217,2219,2221],{"class":191,"line":638},[189,2218,1431],{"class":210},[189,2220,284],{"class":271},[189,2222,334],{"class":210},[189,2224,2225],{"class":191,"line":649},[189,2226,381],{"emptyLinePlaceholder":380},[189,2228,2229,2231,2234,2236,2238,2241,2243],{"class":191,"line":657},[189,2230,1803],{"class":202},[189,2232,2233],{"class":225}," xhr",[189,2235,393],{"class":210},[189,2237,396],{"class":210},[189,2239,2240],{"class":206}," XMLHttpRequest",[189,2242,402],{"class":271},[189,2244,334],{"class":210},[189,2246,2247],{"class":191,"line":687},[189,2248,381],{"emptyLinePlaceholder":380},[189,2250,2251],{"class":191,"line":703},[189,2252,2253],{"class":195},"    // 监听上传进度\n",[189,2255,2256,2259,2261,2264,2266,2269,2271,2273,2275,2277,2279,2281,2283,2285,2288,2290,2292],{"class":191,"line":731},[189,2257,2258],{"class":225},"    xhr",[189,2260,287],{"class":210},[189,2262,2263],{"class":225},"upload",[189,2265,287],{"class":210},[189,2267,2268],{"class":206},"addEventListener",[189,2270,211],{"class":271},[189,2272,303],{"class":210},[189,2274,1924],{"class":299},[189,2276,303],{"class":210},[189,2278,229],{"class":210},[189,2280,1140],{"class":210},[189,2282,1143],{"class":214},[189,2284,218],{"class":210},[189,2286,2287],{"class":221}," ProgressEvent",[189,2289,284],{"class":210},[189,2291,453],{"class":202},[189,2293,255],{"class":210},[189,2295,2296,2299,2301,2303,2305,2308,2310],{"class":191,"line":740},[189,2297,2298],{"class":267},"      if",[189,2300,1140],{"class":271},[189,2302,1143],{"class":225},[189,2304,287],{"class":210},[189,2306,2307],{"class":225},"lengthComputable",[189,2309,306],{"class":271},[189,2311,309],{"class":210},[189,2313,2314,2317,2320,2322,2324,2326,2328,2331,2334,2337,2339,2342,2344,2347,2351],{"class":191,"line":747},[189,2315,2316],{"class":202},"        const",[189,2318,2319],{"class":225}," percentComplete",[189,2321,393],{"class":210},[189,2323,1140],{"class":271},[189,2325,1143],{"class":225},[189,2327,287],{"class":210},[189,2329,2330],{"class":225},"loaded",[189,2332,2333],{"class":210}," /",[189,2335,2336],{"class":225}," event",[189,2338,287],{"class":210},[189,2340,2341],{"class":225},"total",[189,2343,306],{"class":271},[189,2345,2346],{"class":210},"*",[189,2348,2350],{"class":2349},"sbssI"," 100",[189,2352,334],{"class":210},[189,2354,2355,2358,2360,2363,2365,2368,2370],{"class":191,"line":764},[189,2356,2357],{"class":225},"        onProgress",[189,2359,1308],{"class":210},[189,2361,2362],{"class":206}," onProgress",[189,2364,211],{"class":271},[189,2366,2367],{"class":225},"percentComplete",[189,2369,284],{"class":271},[189,2371,334],{"class":210},[189,2373,2374],{"class":191,"line":791},[189,2375,2376],{"class":210},"      }\n",[189,2378,2379,2381,2383],{"class":191,"line":801},[189,2380,1431],{"class":210},[189,2382,284],{"class":271},[189,2384,334],{"class":210},[189,2386,2387],{"class":191,"line":810},[189,2388,381],{"emptyLinePlaceholder":380},[189,2390,2391,2393,2395,2397,2399,2401,2404,2406,2408,2410,2412],{"class":191,"line":1345},[189,2392,2258],{"class":225},[189,2394,287],{"class":210},[189,2396,2268],{"class":206},[189,2398,211],{"class":271},[189,2400,303],{"class":210},[189,2402,2403],{"class":299},"load",[189,2405,303],{"class":210},[189,2407,229],{"class":210},[189,2409,1228],{"class":210},[189,2411,453],{"class":202},[189,2413,255],{"class":210},[189,2415,2416,2418,2420,2423,2425,2427,2430,2433,2435,2437,2439,2441,2444,2447,2449],{"class":191,"line":1382},[189,2417,2298],{"class":267},[189,2419,1140],{"class":271},[189,2421,2422],{"class":225},"xhr",[189,2424,287],{"class":210},[189,2426,1864],{"class":225},[189,2428,2429],{"class":210}," >=",[189,2431,2432],{"class":2349}," 200",[189,2434,1308],{"class":210},[189,2436,2233],{"class":225},[189,2438,287],{"class":210},[189,2440,1864],{"class":225},[189,2442,2443],{"class":210}," \u003C",[189,2445,2446],{"class":2349}," 300",[189,2448,306],{"class":271},[189,2450,309],{"class":210},[189,2452,2453,2456],{"class":191,"line":1409},[189,2454,2455],{"class":267},"        try",[189,2457,255],{"class":210},[189,2459,2460,2463,2465,2467,2470,2472,2475,2477,2479,2481,2483,2485],{"class":191,"line":1428},[189,2461,2462],{"class":202},"          const",[189,2464,1351],{"class":225},[189,2466,393],{"class":210},[189,2468,2469],{"class":225}," JSON",[189,2471,287],{"class":210},[189,2473,2474],{"class":206},"parse",[189,2476,211],{"class":271},[189,2478,2422],{"class":225},[189,2480,287],{"class":210},[189,2482,668],{"class":225},[189,2484,284],{"class":271},[189,2486,334],{"class":210},[189,2488,2489,2492,2494,2497,2499],{"class":191,"line":1445},[189,2490,2491],{"class":206},"          resolve",[189,2493,211],{"class":271},[189,2495,2496],{"class":225},"result",[189,2498,284],{"class":271},[189,2500,334],{"class":210},[189,2502,2503,2506,2508,2510,2512,2514],{"class":191,"line":1470},[189,2504,2505],{"class":210},"        }",[189,2507,1434],{"class":267},[189,2509,1140],{"class":271},[189,2511,757],{"class":225},[189,2513,306],{"class":271},[189,2515,309],{"class":210},[189,2517,2518,2521,2523,2525,2527,2529,2531,2534,2536,2538],{"class":191,"line":1498},[189,2519,2520],{"class":206},"          reject",[189,2522,211],{"class":271},[189,2524,352],{"class":210},[189,2526,355],{"class":206},[189,2528,211],{"class":271},[189,2530,303],{"class":210},[189,2532,2533],{"class":299},"响应解析失败",[189,2535,303],{"class":210},[189,2537,366],{"class":271},[189,2539,334],{"class":210},[189,2541,2542],{"class":191,"line":1504},[189,2543,2544],{"class":210},"        }\n",[189,2546,2547,2550,2552],{"class":191,"line":1514},[189,2548,2549],{"class":210},"      }",[189,2551,1509],{"class":267},[189,2553,255],{"class":210},[189,2555,2556,2559,2561,2563,2565,2567,2569,2571,2573,2575,2577,2580,2582,2584],{"class":191,"line":1532},[189,2557,2558],{"class":206},"        reject",[189,2560,211],{"class":271},[189,2562,352],{"class":210},[189,2564,355],{"class":206},[189,2566,211],{"class":271},[189,2568,1851],{"class":210},[189,2570,1479],{"class":299},[189,2572,1857],{"class":210},[189,2574,2422],{"class":225},[189,2576,287],{"class":210},[189,2578,2579],{"class":225},"statusText",[189,2581,1867],{"class":210},[189,2583,366],{"class":271},[189,2585,334],{"class":210},[189,2587,2588],{"class":191,"line":1537},[189,2589,2376],{"class":210},[189,2591,2592,2594,2596],{"class":191,"line":1542},[189,2593,1431],{"class":210},[189,2595,284],{"class":271},[189,2597,334],{"class":210},[189,2599,2600],{"class":191,"line":1547},[189,2601,381],{"emptyLinePlaceholder":380},[189,2603,2604,2606,2608,2610,2612,2614,2616,2618,2620,2622,2624],{"class":191,"line":1553},[189,2605,2258],{"class":225},[189,2607,287],{"class":210},[189,2609,2268],{"class":206},[189,2611,211],{"class":271},[189,2613,303],{"class":210},[189,2615,757],{"class":299},[189,2617,303],{"class":210},[189,2619,229],{"class":210},[189,2621,1228],{"class":210},[189,2623,453],{"class":202},[189,2625,255],{"class":210},[189,2627,2628,2630,2632,2634,2636,2638,2640,2643,2645,2647],{"class":191,"line":1576},[189,2629,2110],{"class":206},[189,2631,211],{"class":271},[189,2633,352],{"class":210},[189,2635,355],{"class":206},[189,2637,211],{"class":271},[189,2639,303],{"class":210},[189,2641,2642],{"class":299},"网络错误",[189,2644,303],{"class":210},[189,2646,366],{"class":271},[189,2648,334],{"class":210},[189,2650,2651,2653,2655],{"class":191,"line":1593},[189,2652,1431],{"class":210},[189,2654,284],{"class":271},[189,2656,334],{"class":210},[189,2658,2659],{"class":191,"line":1598},[189,2660,381],{"emptyLinePlaceholder":380},[189,2662,2663,2665,2667,2669,2671,2673,2676,2678,2680,2682,2684],{"class":191,"line":1603},[189,2664,2258],{"class":225},[189,2666,287],{"class":210},[189,2668,2268],{"class":206},[189,2670,211],{"class":271},[189,2672,303],{"class":210},[189,2674,2675],{"class":299},"abort",[189,2677,303],{"class":210},[189,2679,229],{"class":210},[189,2681,1228],{"class":210},[189,2683,453],{"class":202},[189,2685,255],{"class":210},[189,2687,2688,2690,2692,2694,2696,2698,2700,2703,2705,2707],{"class":191,"line":1620},[189,2689,2110],{"class":206},[189,2691,211],{"class":271},[189,2693,352],{"class":210},[189,2695,355],{"class":206},[189,2697,211],{"class":271},[189,2699,303],{"class":210},[189,2701,2702],{"class":299},"上传被取消",[189,2704,303],{"class":210},[189,2706,366],{"class":271},[189,2708,334],{"class":210},[189,2710,2711,2713,2715],{"class":191,"line":1653},[189,2712,1431],{"class":210},[189,2714,284],{"class":271},[189,2716,334],{"class":210},[189,2718,2719],{"class":191,"line":1662},[189,2720,381],{"emptyLinePlaceholder":380},[189,2722,2723,2725,2727,2730,2732,2734,2736,2738,2740,2742,2744],{"class":191,"line":1667},[189,2724,2258],{"class":225},[189,2726,287],{"class":210},[189,2728,2729],{"class":206},"open",[189,2731,211],{"class":271},[189,2733,303],{"class":210},[189,2735,630],{"class":299},[189,2737,303],{"class":210},[189,2739,229],{"class":210},[189,2741,232],{"class":225},[189,2743,284],{"class":271},[189,2745,334],{"class":210},[189,2747,2748,2750,2752,2755,2757,2760,2762],{"class":191,"line":1672},[189,2749,2258],{"class":225},[189,2751,287],{"class":210},[189,2753,2754],{"class":206},"send",[189,2756,211],{"class":271},[189,2758,2759],{"class":225},"formData",[189,2761,284],{"class":271},[189,2763,334],{"class":210},[189,2765,2766,2768,2770],{"class":191,"line":1712},[189,2767,516],{"class":210},[189,2769,284],{"class":271},[189,2771,334],{"class":210},[189,2773,2774],{"class":191,"line":1717},[189,2775,813],{"class":210},[132,2777,2778],{"id":2778},"注意事项",[174,2780,2782],{"id":2781},"_1-环境限制","1. 环境限制",[2784,2785,2786,2794],"ul",{},[142,2787,2788,2789,2793],{},"此解决方案",[2790,2791,2792],"strong",{},"仅适用于 H5 环境","，在小程序和 App 环境中无法使用",[142,2795,2796],{},"需要检测当前运行环境，避免在非 H5 环境下执行",[174,2798,2800],{"id":2799},"_2-fetch-响应处理","2. Fetch 响应处理",[2784,2802,2803,2810],{},[142,2804,2805,2806,2809],{},"使用 ",[112,2807,123],{"href":121,"rel":2808},[116]," 时，需要先将响应转换为 JSON 格式",[142,2811,2812,2813,2817,2818,2823],{},"在 ",[112,2814,663],{"href":2815,"rel":2816},"https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/then",[116]," 中先进行 ",[112,2819,2822],{"href":2820,"rel":2821},"https://developer.mozilla.org/zh-CN/docs/Web/API/Body/json",[116],"response.json()"," 处理，然后再进行后续操作",[174,2825,2827],{"id":2826},"_3-formdata-使用","3. FormData 使用",[2784,2829,2830,2836],{},[142,2831,2832,2835],{},[112,2833,129],{"href":127,"rel":2834},[116]," 允许我们轻松地构建表单数据",[142,2837,2838,2839,2844],{},"可以通过 ",[112,2840,2843],{"href":2841,"rel":2842},"https://developer.mozilla.org/zh-CN/docs/Web/API/FormData/append",[116],"append()"," 方法添加多个同名字段，后端会接收到文件数组",[132,2846,2847],{"id":2847},"总结",[108,2849,2850,2851,2854,2855,168,2858,2861],{},"虽然 ",[112,2852,117],{"href":114,"rel":2853},[116]," 有其局限性，但在 H5 环境下，我们可以利用原生的 ",[112,2856,123],{"href":121,"rel":2857},[116],[112,2859,129],{"href":127,"rel":2860},[116]," 来实现多文件上传功能。需要注意的是：",[139,2863,2864,2867,2873,2876],{},[142,2865,2866],{},"此方法仅适用于 H5 环境",[142,2868,2869,2872],{},[112,2870,123],{"href":121,"rel":2871},[116]," 响应需要先进行 JSON 处理",[142,2874,2875],{},"需要适当处理错误和上传进度",[142,2877,2878],{},"后端需要支持接收多文件数组",[108,2880,2881],{},"通过这种方式，我们可以在 H5 环境中实现更灵活的多文件上传功能。",[2883,2884,2885],"blockquote",{},[108,2886,2887],{},"（注：文档内容由 Copilot 生成）",[2889,2890,2891],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":184,"searchDepth":199,"depth":199,"links":2893},[2894,2895,2900,2905],{"id":134,"depth":199,"text":134},{"id":160,"depth":199,"text":161,"children":2896},[2897,2898,2899],{"id":176,"depth":258,"text":177},{"id":816,"depth":258,"text":817},{"id":1893,"depth":258,"text":1894},{"id":2778,"depth":199,"text":2778,"children":2901},[2902,2903,2904],{"id":2781,"depth":258,"text":2782},{"id":2799,"depth":258,"text":2800},{"id":2826,"depth":258,"text":2827},{"id":2847,"depth":199,"text":2847},"2025-12-24T00:00:00.000Z","探讨如何在 H5 环境下通过 fetch + FormData 解决 uni.upload 无法在一个接口上传多个文件的问题","md",{"src":2910},"https://picsum.photos/id/108/640/360",{},{"title":68,"description":2907},"wlyg417BbsTwrM78Lg8RyxzX-YU7IsPuEcCAPsxVyP8",[2915,2917],{"title":64,"path":65,"stem":66,"description":2916,"children":-1},"介绍如何根据 Apifox 文档自动生成类型安全的 API 请求文件，提高开发效率",{"title":72,"path":73,"stem":74,"description":2918,"children":-1},"解决Wangeditor对div中img标签的过滤问题，特别是处理第三方接口导入商品详情时的兼容性问题",1774239529537]