11const { FileBox } = require ( 'file-box' )
22const MIME = require ( 'mime' )
33const { logger } = require ( './log' )
4+ const { URL } = require ( 'url' )
45/**
56 * 下载媒体文件转化为Buffer
67 * @param {string } fileUrl
7- * @returns {Promise<{buffer?: Buffer, fileName?: string}> }
8+ * @returns {Promise<{buffer?: Buffer, fileName?: string, fileNameAlias?: string }> }
89 */
910const downloadFile = async ( fileUrl ) => {
1011 try {
1112 const response = await fetch ( fileUrl )
1213
1314 if ( response . ok ) {
1415 const buffer = Buffer . from ( await response . arrayBuffer ( ) )
15- let fileName = getFileNameFromUrl ( fileUrl )
16+ // 使用自定义文件名,解决URL无文件后缀名时,文件被微信解析成不正确的后缀问题
17+ let { fileName, query } = getFileInfoFromUrl ( fileUrl )
1618
1719 // deal with unValid Url format like https://pangji-home.com/Fi5DimeGHBLQ3KcELn3DolvENjVU
1820 if ( fileName === '' ) {
@@ -24,7 +26,8 @@ const downloadFile = async (fileUrl) => {
2426
2527 return {
2628 buffer,
27- fileName
29+ fileName,
30+ fileNameAlias : query ?. $alias
2831 }
2932 }
3033
@@ -36,25 +39,29 @@ const downloadFile = async (fileUrl) => {
3639}
3740
3841/**
42+ * @typedef {{fileName: string, query: null | Record<string, string>} } fileInfoObj
3943 * 从url中提取文件名
4044 * @param {string } url
41- * @returns {string }
45+ * @returns {fileInfoObj }
4246 * @example 参数 url 示例
4347 * valid: "http://www.baidu.com/image.png?a=1 => image.png"
4448 * notValid: "https://pangji-home.com/Fi5DimeGHBLQ3KcELn3DolvENjVU => ''"
4549 */
46- const getFileNameFromUrl = ( url ) => {
47- const matchRes = url . match ( / .* \/ ( [ ^ / ? ] * ) / ) ?. [ 1 ]
48-
49- if ( matchRes === undefined ) return ''
50+ const getFileInfoFromUrl = ( url ) => {
51+ /** @type {fileInfoObj } */
52+ let matchRes = {
53+ fileName : url . match ( / .* \/ ( [ ^ / ? ] * ) / ) ?. [ 1 ] || '' , // fileName has string.string is Valid filename
54+ query : null
55+ }
5056
51- const checkMathDotPosition = matchRes . indexOf ( '.' )
52- // fileName has string.string is Valid filename
53- if ( checkMathDotPosition > - 1 ) {
54- return matchRes
55- } else {
56- return ''
57+ try {
58+ const urlObj = new URL ( url )
59+ matchRes . query = Object . fromEntries ( urlObj . searchParams )
60+ } catch ( e ) {
61+ // make ts happy
5762 }
63+
64+ return matchRes
5865}
5966
6067/**
@@ -63,9 +70,9 @@ const getFileNameFromUrl = (url) => {
6370 * @returns {Promise<import('file-box').FileBoxInterface> }
6471 */
6572const getMediaFromUrl = async ( url ) => {
66- const { buffer, fileName } = await downloadFile ( url )
73+ const { buffer, fileName, fileNameAlias } = await downloadFile ( url )
6774 //@ts -expect-errors buffer 解析是吧的情况
68- return FileBox . fromBuffer ( buffer , fileName )
75+ return FileBox . fromBuffer ( buffer , fileNameAlias || fileName )
6976}
7077
7178/**
@@ -187,7 +194,6 @@ module.exports = {
187194 ...require ( './nextTick.js' ) ,
188195 ...require ( './paramsValid.js' ) ,
189196 ...require ( './log.js' ) ,
190- getFileNameFromUrl,
191197 getMediaFromUrl,
192198 getBufferFile,
193199 generateToken,
0 commit comments