首页 > 解决方案 > 如何通过读取 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 获取到文件中

标签: javascriptnode.jspuppeteer

解决方案


首先,我放弃了 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);
  } 

推荐阅读