Не удалось загрузить файл PDF в React js - PullRequest
2 голосов
/ 22 марта 2020

Я работаю над простым веб-приложением реагирования, которое добавляет и извлекает файлы в / из IPFS.

Когда файл добавляется в IPFS, имя добавляемого файла (т. Е. Медицинский файл) также как кнопка «Просмотр файла» появится на странице.

Когда кнопка нажата, файл должен быть просмотрен с использованием компонента «Документ» в response-pdf [https://www.npmjs.com/package/ Reaction-pdf | (Файл документа = "...". Файл может быть URL-адресом, содержимым base64, Uint8Array и т. Д.)

Добавление и получение файлов из IPFS работают успешно. Полученный из IPFS файл в виде Uint8Array передается компоненту Document внутри компонента Main. js для просмотра файла PDF. Однако странице не удалось загрузить файл PDF. Кроме того, я получил ошибку:

Error: "Setting up fake worker failed: "window.pdfjsWorker is undefined"."

Обратите внимание, что у меня есть следующее в главном. js:

  <Document file={{ data: pdfFile.content }}></Document>

Приложение. js

      import React, { Component } from "react";
import Web3 from "web3";
import "./App.css";
import Meme from "../abis/Meme";
import Addressbar from "./Addressbar";
import Main from "./Main";

class App extends Component {
  async componentDidMount() {
    await this.getWeb3Provider();
    this.loadBlockchainData();
  }

  async getWeb3Provider() {
    if (window.ethereum) {
      window.web3 = new Web3(window.ethereum);
      await window.ethereum.enable();
    } else if (window.web3) {
      window.web3 = new Web3(window.web3.currentProvider);
    } else {
      window.alert(
        "Non-Ethereum browser detected. You should consider trying MetaMask!"
      );
    }
  }

  async loadBlockchainData() {
    const web3 = window.web3;
    // Load the account
    const accounts = await web3.eth.getAccounts();
    this.setState({ account: accounts[0] });
    /*Get an instance of the deployed smart contract in Javascript to allow us to 
     call the functions of the smart contract*/
    const networkId = await web3.eth.net.getId();
    const networkData = Meme.networks[networkId];
    if (networkData) {
      const contract = new web3.eth.Contract(Meme.abi, networkData.address);
      this.setState({ contract: contract });

      // Fetching the file hashes from the smart contract
      const count = await contract.methods.getfileHashesCount().call();
      for (var i = 0; i < count; i++) {
        const fileHash = await contract.methods.fileHashes(i).call();
        this.setState({
          fileHashes: [...this.state.fileHashes, fileHash]
        });
      }
    } else {
      window.alert("The contract is not found in your blockchain.");
    }
  }

  constructor(props) {
    super(props);
    // Setting the account (1)
    this.state = {
      account: null,
      fileHashes: [],
      contract: null,
      buffer: null
    };
  }

  // Setting the buffer
  setBuffer = data => {
    this.setState({ buffer: data });
    console.log("buffer data", this.state.buffer);
  };

  // Storing/adding the file hash on the blockchain
  storeFileHash = hash => {
    this.state.contract.methods
      .addFileHash(hash)
      .send({ from: this.state.account })
      .then(r => {
        return this.setState({ fileHashes: [...this.state.fileHashes, hash] });
      });

    //console.log("fileHashes", this.state.fileHashes);
  };

  render() {
    return (
      <div className="container">
        <div>
          <Addressbar account={this.state.account} />
        </div>

        <div>
          <Main
            fileHashes={this.state.fileHashes}
            setBuffer={this.setBuffer}
            buffer={this.state.buffer}
            storeFileHash={this.storeFileHash}
          />
        </div>
      </div>
    );
  }
}

export default App;

Main. Js

    import React, { Component } from "react";
import { Document, Page } from "react-pdf";
//import { Document } from "react-pdf/dist/entry.webpack";
//import { pdfjs } from "react-pdf";
//pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

//Required module(s)
const ipfsAPI = require("ipfs-api");

/*** Connceting to the ipfs network via infura gateway ***/
const ipfs = ipfsAPI("ipfs.infura.io", "5001", { protocol: "https" });

export class Main extends Component {
  /*
  state = {
    pdfFiles: []
  };
  */
  state = {
    pdfFiles: [],
    text: "Hi World"
  };

  captureFile = event => {
    event.preventDefault();
    // Fetch the file chosen
    const file = event.target.files[0];
    console.log("The original file : ", file);
    // Convert the file to a buffer
    const reader = new window.FileReader();
    reader.readAsArrayBuffer(file);
    reader.onloadend = () => {
      const arr = new Uint8Array(reader.result);
      console.log("Uint8Array ouptut", arr);
      console.log("reader.result output : ", reader.result);
      console.log("Buffer(reader.result) output : ", Buffer(reader.result));
      this.props.setBuffer(Buffer(reader.result));
    };
  };

  onSubmit = event => {
    event.preventDefault();
    console.log("Submitting file to IPFS......");
    console.log(this.props.buffer);

    // Adding the file to IPFS
    ipfs.files.add(this.props.buffer, (error, result) => {
      if (error) {
        console.log(error);
        return;
      }
      console.log("File added succesfully");
      console.log("IPFS result", result);

      // Storing the file hash on the blockchain
      this.props.storeFileHash(result[0].hash);
    });
  }; // end of sumbit event

  onClick = event => {
    event.preventDefault();
    console.log("Button clicked......");
    console.log(this.state.text);

    /*** Getting the uploaded file via hash code ***/
    const that = this; // NECESSARY
    ipfs.files.cat(event.target.name, function(err, file) {
      console.log("Getting files from IPFS ....... ");
      //console.log("File path ", file.path);
      //console.log("File hash", file.hash);
      console.log("The Unit8Array file content: ", file);
      const unit8Array_ = {
        content: file
      };
      console.log("Printing (1)......", unit8Array_.content);
      that.setState({ text: "Hi America" });
      console.log(that.state.text);
      that.setState({ pdfFiles: [...that.state.pdfFiles, unit8Array_] });
    });
  }; // end of sumbit event

  render() {
    return (
      <div className="container-fluid mt-5">
        <div className="row">
          <main>
            <div>
              <h3>Medical Files-Upload: </h3>
              <form onSubmit={this.onSubmit}>
                <div>
                  <label className="mr-2">Upload your medical document:</label>
                  <input type="file" onChange={this.captureFile} />
                  <input type="submit" />
                </div>
              </form>
            </div>

            <hr></hr>

            <div>
              <h5>PDF Document: {this.state.text} </h5>
              {this.state.pdfFiles.map((pdfFile, key) => {
                return (
                  <div>
                    <p>{console.log("Printing (2)....", pdfFile.content)}</p>
                    <Document file={{ data: pdfFile.content }}></Document>
                  </div>
                );
              })}
            </div>

            <hr></hr>
            <div>
              <h3>Medical Files-View: </h3>
              {this.props.fileHashes.map((fileHash, key) => {
                return (
                  <p>
                    {" "}
                    Medical File{" "}
                    <button name={fileHash} onClick={this.onClick}>
                      View File
                    </button>{" "}
                  </p>
                );
              })}
            </div>
          </main>
        </div>
      </div>
    );
  }
}

export default Main;

Адресная строка. js

import React, { Component } from "react";

class Addressbar extends Component {
  render() {
    return (
      <nav className="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow">
        <ul className="navbar-nav px-3">
          <li className="nav-item text-nowrap d-none d-sm-none d-sm-block">
            <small className="text-white">
              <span id="account">
                {"Your account address: " + this.props.account}
              </span>
            </small>
          </li>
        </ul>
      </nav>
    );
  }
}

export default Addressbar;
...