javascript - 如何通过读取 Nodejs 中的文件在 Bowser 中构造一个新文件?
问题描述
我正在使用 puppeteer 运行一些自动化测试。其中一项测试包括上传文件。如何在 Nodejs 中读取文件并在浏览器中生成新文件。我觉得我很接近,但我似乎无法将数据转换为正确的类型。
这是我正在尝试的。
我也在使用这个简单的包:cross-blob
const puppeteer = require('puppeteer');
const fs = require('fs');
const Blob = require("cross-blob");
const browser = await puppeteer.launch({headless: false});
const page = await browser.newPage();
await page.goto('testwebsite.com');
const dropzone = await page.$('#dropzone');
const fileData = fs.readFileSync('test.jpg');
const blob = new Blob(fileData);
console.log(blob); // <-- Logging out blog looks good to me.
await page.waitFor(1000);
try {
await page.evaluate((blob) => {
const file = new File([blob], 'test.jpg');
var fakeDropEvent = new DragEvent('drop');
var dT = new DataTransfer();
dT.items.add(file);
Object.defineProperty(fakeDropEvent, 'dataTransfer', {
value: dT
});
window.dispatchEvent(fakeDropEvent);
}, blob);
} catch (error) {
console.log(error);
}
当我在“drop”之后在浏览器中注销文件时,我看到以下文件:
0: File
name: "test.jpg"
lastModified: 1587457550129
lastModifiedDate: Tue Apr 21 2020 01:25:50 GMT-0700 (Pacific Daylight Time) {}
webkitRelativePath: ""
size: 15 // <-- This is not right.
type: "" // <-- This is also incorrect.
如何将我在 Node 中创建的文件 blob 获取到文件中
解决方案
首先,我放弃了 cross-blob 包。
我想出的解决方案是在存在本机功能的浏览器中创建 Blob,并将 base64 编码的字符串传递给浏览器。
首先,我将文件读入缓冲区,并将其编码为 base64 字符串,我可以将其传递给 puppeteer。
const filebuffer = fs.readFileSync('test.jpg');
const rawBase64 = filebuffer.toString('base64');
const base64 = `data:image/jpeg;base64,${rawBase64}`;
如果您要发送到浏览器,最后一行是必不可少的,因为它期望 base64 编码的字符串具有我在上面连接的识别前缀。
接下来,我将其传递给 puppeteer,并将其转换为 Blob。
try {
await page.evaluate((base64) => {
var blob = convertBase64ToBlob(base64);
var file = new File([blob], 'test.jpg', {type: 'image/jpeg'});
var fakeDropEvent = new DragEvent('drop');
var dT = new DataTransfer();
dT.dropEffect = "none";
dT.effectAllowed = "all";
dT.items.add(file);
Object.defineProperty(fakeDropEvent, 'dataTransfer', {
value: dT
});
window.dispatchEvent(fakeDropEvent);
console.log("Processing Image...");
function convertBase64ToBlob(Base64Image) {
// Split into two parts
const parts = Base64Image.split(';base64,');
// Hold the content type
const imageType = parts[0].split(':')[1];
// Decode Base64 string
const decodedData = window.atob(parts[1]);
// Create UNIT8ARRAY of size same as row data length
const uInt8Array = new Uint8Array(decodedData.length);
// Insert all character code into uInt8Array
for (let i = 0; i < decodedData.length; ++i) {
uInt8Array[i] = decodedData.charCodeAt(i);
}
// Return BLOB image after conversion
return new Blob([uInt8Array], { type: imageType });
}
}, base64); // <-- Passing value to evaluate method.
} catch (error) {
console.log(error);
}
推荐阅读
- javascript - 使用 Spring Boot、JavaScript 和 Ajax 进行电子商务的多个复选框产品过滤器,例如 Amazon 或 Flipkart
- python - Django REST 框架,序列化器:附加数据?
- php - php json数组数组并从深层嵌套中获取一些键值
- javascript - 如何通过 Firebase 函数将参数传递给外部 API
- java - 改造不显示任何数据
- java - 在 getListEntryObjects 中设置 max_Retrieve 和 sort_list 参数
- php - Json响应在刀片文件的Laravel中返回未定义的值
- php - 从 PHP 获取 Nginx 配置变量值
- git - 如何在 GitBash 中删除分支?
- angular - 错误:包路径 ./compat 未从包中导出