diff --git a/README.md b/README.md index a42cb8a..67454ae 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,8 @@ Authorization: Bearer [refresh_token] ### 文件上传解读 +提供一个可访问的文件URL或者BASE64_URL进行解析。 + 请求数据: ```json { @@ -105,6 +107,8 @@ Authorization: Bearer [refresh_token] ### 图像解析 +提供一个可访问的图像URL或者BASE64_URL进行解析。 + 此格式兼容 [gpt-4-vision-preview](https://platform.openai.com/docs/guides/vision) API格式,您也可以用这个格式传送文档进行解析。 请求数据: diff --git a/package.json b/package.json index 01ee45f..6f849e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kimi-free-api", - "version": "0.0.7", + "version": "0.0.8", "description": "Kimi Free API Server", "type": "module", "main": "dist/index.js", diff --git a/src/api/controllers/chat.ts b/src/api/controllers/chat.ts index 8ee5156..a0435a8 100644 --- a/src/api/controllers/chat.ts +++ b/src/api/controllers/chat.ts @@ -298,6 +298,8 @@ async function preSignUrl(filename: string, refreshToken: string) { * @param fileUrl 文件URL */ async function checkFileUrl(fileUrl: string) { + if(util.isBASE64Data(fileUrl)) + return; const result = await axios.head(fileUrl, { timeout: 15000, validateStatus: () => true @@ -322,24 +324,34 @@ async function uploadFile(fileUrl: string, refreshToken: string) { // 预检查远程文件URL可用性 await checkFileUrl(fileUrl); + let filename, fileData, mimeType; + // 如果是BASE64数据则直接转换为Buffer + if(util.isBASE64Data(fileUrl)) { + mimeType = util.extractBASE64DataFormat(fileUrl); + const ext = mime.getExtension(mimeType); + filename = `${util.uuid()}.${ext}`; + fileData = Buffer.from(util.removeBASE64DataHeader(fileUrl), 'base64'); + } // 下载文件到内存,如果您的服务器内存很小,建议考虑改造为流直传到下一个接口上,避免停留占用内存 - const filename = path.basename(fileUrl); - const { data: fileData } = await axios.get(fileUrl, { - responseType: 'arraybuffer', - // 100M限制 - maxContentLength: FILE_MAX_SIZE, - // 60秒超时 - timeout: 60000 - }); + else { + filename = path.basename(fileUrl); + ({ data: fileData } = await axios.get(fileUrl, { + responseType: 'arraybuffer', + // 100M限制 + maxContentLength: FILE_MAX_SIZE, + // 60秒超时 + timeout: 60000 + })); + } // 获取预签名文件URL const { url: uploadUrl, object_name: objectName } = await preSignUrl(filename, refreshToken); - + // 获取文件的MIME类型 - const mimeType = mime.getType(filename); + mimeType = mimeType || mime.getType(filename); // 上传文件到目标OSS const token = await acquireToken(refreshToken); let result = await axios.request({ diff --git a/src/index.ts b/src/index.ts index 384f004..b5e960e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,7 +23,7 @@ const startupTime = performance.now(); await server.listen(); config.service.bindAddress && - logger.success("service bind address:", config.service.bindAddress); + logger.success("Service bind address:", config.service.bindAddress); })() .then(() => logger.success( diff --git a/src/lib/util.ts b/src/lib/util.ts index 8a89f65..c15706c 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -136,18 +136,18 @@ const util = { return !_.isUndefined(value) && /^[a-zA-Z0-9\/\+]+(=?)+$/.test(value); }, - isBASE64Image(value) { - return /^data:image/.test(value); + isBASE64Data(value) { + return /^data:/.test(value); }, - extractBASE64ImageFormat(value): string | null { - const match = value.trim().match(/^data:image\/(.+);base64,/); + extractBASE64DataFormat(value): string | null { + const match = value.trim().match(/^data:(.+);base64,/); if(!match) return null; return match[1]; }, - removeBASE64ImageHeader(value): string { - return value.replace(/^data:image\/(.+);base64,/, ""); + removeBASE64DataHeader(value): string { + return value.replace(/^data:(.+);base64,/, ""); }, isDataString(value): boolean {