mirror of
https://github.com/foxhui/WebAI2API.git
synced 2026-06-16 21:03:59 +08:00
fix: 修复 Gemini 图片无法上传问题
This commit is contained in:
@@ -2,7 +2,7 @@ import { initBrowserBase } from '../../browser/launcher.js';
|
||||
import {
|
||||
sleep,
|
||||
safeClick,
|
||||
pasteImages
|
||||
uploadFilesViaChooser
|
||||
} from '../../browser/utils.js';
|
||||
import {
|
||||
fillPrompt,
|
||||
@@ -58,23 +58,22 @@ async function generateImage(context, prompt, imgPaths, modelId, meta = {}) {
|
||||
await inputLocator.waitFor({ timeout: 30000 });
|
||||
await sleep(1500, 2500);
|
||||
|
||||
// 2. 上传图片
|
||||
// 2. 上传图片 (使用 filechooser 事件,因为 Firefox 不会创建 DOM input 元素)
|
||||
if (imgPaths && imgPaths.length > 0) {
|
||||
const expectedUploads = imgPaths.length;
|
||||
let uploadedCount = 0;
|
||||
// 点击加号按钮打开菜单
|
||||
logger.debug('适配器', '点击加号按钮...', meta);
|
||||
const uploadMenuBtn = page.getByRole('button', { name: 'Open upload file menu' });
|
||||
await safeClick(page, uploadMenuBtn, { bias: 'button' });
|
||||
await sleep(500, 1000);
|
||||
|
||||
await pasteImages(page, inputLocator, imgPaths, {
|
||||
// 使用公共函数上传文件
|
||||
const uploadFilesBtn = page.getByRole('button', { name: /Upload files/ });
|
||||
await uploadFilesViaChooser(page, uploadFilesBtn, imgPaths, {
|
||||
uploadValidator: (response) => {
|
||||
const url = response.url();
|
||||
// 检测上传成功:google.com/upload/?upload_id= 的 POST 请求
|
||||
if (response.status() === 200 &&
|
||||
return response.status() === 200 &&
|
||||
url.includes('google.com/upload/') &&
|
||||
url.includes('upload_id=')) {
|
||||
uploadedCount++;
|
||||
logger.info('适配器', `图片上传进度: ${uploadedCount}/${expectedUploads}`, meta);
|
||||
return uploadedCount >= expectedUploads;
|
||||
}
|
||||
return false;
|
||||
url.includes('upload_id=');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -404,6 +404,76 @@ export async function pasteImages(page, target, filePaths, options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 filechooser 事件上传文件 (适用于无 DOM input 元素的场景,如 Firefox)
|
||||
* @param {import('playwright-core').Page} page - Playwright 页面对象
|
||||
* @param {string|import('playwright-core').ElementHandle|import('playwright-core').Locator} triggerTarget - 触发文件选择的按钮
|
||||
* @param {string[]} filePaths - 文件路径数组
|
||||
* @param {Object} [options] - 可选配置
|
||||
* @param {Function} [options.uploadValidator] - 自定义上传确认回调函数, 接收 response 参数,返回 true 表示该响应代表一次成功上传
|
||||
* @param {number} [options.timeout=60000] - 上传超时时间 (毫秒)
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function uploadFilesViaChooser(page, triggerTarget, filePaths, options = {}) {
|
||||
if (!filePaths || filePaths.length === 0) return;
|
||||
|
||||
const timeout = options.timeout || 60000;
|
||||
const expectedUploads = filePaths.length;
|
||||
let uploadedCount = 0;
|
||||
|
||||
logger.info('浏览器', `正在处理 ${filePaths.length} 张图片 (filechooser 模式)...`);
|
||||
|
||||
// 设置上传确认监听
|
||||
const uploadPromise = new Promise((resolve) => {
|
||||
if (!options.uploadValidator) {
|
||||
// 无验证器,直接 resolve
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
const timeoutId = setTimeout(() => {
|
||||
cleanup();
|
||||
logger.warn('浏览器', `图片上传等待超时 (已确认: ${uploadedCount}/${expectedUploads})`);
|
||||
resolve();
|
||||
}, timeout);
|
||||
|
||||
const onResponse = (response) => {
|
||||
if (options.uploadValidator(response)) {
|
||||
uploadedCount++;
|
||||
logger.info('浏览器', `图片上传进度: ${uploadedCount}/${expectedUploads}`);
|
||||
if (uploadedCount >= expectedUploads) {
|
||||
cleanup();
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const cleanup = () => {
|
||||
clearTimeout(timeoutId);
|
||||
page.off('response', onResponse);
|
||||
};
|
||||
|
||||
page.on('response', onResponse);
|
||||
});
|
||||
|
||||
// 设置等待 filechooser 事件(在点击之前)
|
||||
const fileChooserPromise = page.waitForEvent('filechooser');
|
||||
|
||||
// 点击触发按钮
|
||||
await safeClick(page, triggerTarget, { bias: 'button' });
|
||||
|
||||
// 等待 filechooser 事件并设置文件
|
||||
const fileChooser = await fileChooserPromise;
|
||||
await fileChooser.setFiles(filePaths);
|
||||
logger.debug('浏览器', '已通过 filechooser 提交文件');
|
||||
|
||||
// 等待上传完成(如果有验证器)
|
||||
if (options.uploadValidator) {
|
||||
await uploadPromise;
|
||||
logger.info('浏览器', '所有图片上传完成');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查页面是否有效
|
||||
* @param {import('playwright-core').Page} page
|
||||
|
||||
Reference in New Issue
Block a user