EOS [EOS DAPP 开发] 07 - 使用 ipfs-api 从前端访问 IPFS

pendingauth · 2019年05月17日 · 65 次阅读

本文转载自币乎,作者松果,原文链接:https://bihu.com/article/1474682279

跨域配置

到目前为止,我们的DAPP要运行起来,需要启动3个进程:

  • react localhost:3000

  • nodeos localhost:8888

  • ipfs localhost:5002

就是这样的:

那么就会存在一个问题,我们写的DAPP是一个React应用,它在3000端口,和nodeos的8888端口、IPFS的5002端口不是同源的,因此,React要访问nodeos和IPFS,需要对nodeos和IPFS进行跨域配置,否则会报CORS错误。

nodeos的跨域配置

有两种方法:

1.在启动nodeos时,添加参数:

nodeos -e --access-control-allow-origin='*'

2.修改 .local/share/eosio/nodeos/config/config.ini,添加如下配置:

access-control-allow-origin = *

IPFS跨域配置

可以通过如下命令查看本地IPFS的配置项:

jsipfs config show

然后使用如下命令,为IPFS配置跨域:

jsipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["GET","POST"]'
jsipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'
jsipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials '["true"]'
jsipfs config --json API.HTTPHeaders.Access-Control-Allow-Headers '["Authorization"]'
jsipfs config --json API.HTTPHeaders.Access-Control-Expose-Headers '["Location"]'

配置好后,在输入 jsipfs config show 命令,可以看到如下信息:

使用ipfs-api从前端访问IPFS

先确保已安装ipfs-api:

npm install ipfs-api --save

然后使用 jsipfs daemon 命令启动本地IPFS节点。

在src目录下,新建的ipfsUtils.js文件,封装了ipfs-api的主要功能:

import IpfsAPI from 'ipfs-api';

const ipfs = IpfsAPI('localhost', '5002', {protocol: 'http'});
const ipfsPrefix = "http://localhost:5002/ipfs/";

/**
 * 保存文本到IPFS
 */
export const saveTextToIPFS = (text) => {
  return new Promise((resolve, reject) => {
    const descBuf = Buffer.from(text, 'utf-8');
    ipfs.add(descBuf).then(res => {
      resolve(res[0].hash);
    }).catch(error => {
      console.log(error);
    });
  });
};

/**
 * 从IPFS读取文本
 */
export const readTextFromIPFS = (hash) => {
  return new Promise((resolve, reject) => {
    ipfs.cat(hash).then(res => {
      let content = new TextDecoder('utf-8').decode(res);
      resolve(content);
    }).catch(error => {
      console.log(error);
    });
  });
};

/**
 * 保存文件到IPFS
 */
export const saveFileToIPFS = (file) => {
  return new Promise((resolve, reject) => {
    let reader = new FileReader();
    reader.readAsArrayBuffer(file);
    reader.onloadend = () => {
      const buffer = Buffer.from(reader.result);
      ipfs.add(buffer).then(res => {
        resolve(res[0].hash);
      }).catch(error => {
        console.log(error);
      });
    };
  });
};

/**
 * 通过哈希值访问IPFS上的文件 
 */
export const ipfsUrl = (hash) => {
  return ipfsPrefix + hash;
};

然后在App.js使用ipfs-api的功能,代码如下:

import React, { Component, Fragment } from 'react';
import { Button, Input } from 'antd';

import * as ipfsUtils from './ipfsUtils';

class App extends Component {

  state = {
    textInput: '',
    textOutput: '',
    textHash: '',   
  }

  constructor(props){
    super(props);
    this.handlePush = this.handlePush.bind(this);
    this.handlePull = this.handlePull.bind(this);
    this.handleInputChange = this.handleInputChange.bind(this);
  }

  render() {
    const { textInput, textOutput, textHash } = this.state;

    return (
      <Fragment>
        <Input value={textInput} onChange={this.handleInputChange}></Input>
        <Button onClick={this.handlePush}>提交数据到IPFS</Button>
        <hr/>
        <p>hash is: {textHash}</p>
        <Button onClick={this.handlePull}>从IPFS读取数据</Button>
        <hr/>
        <p>{textOutput}</p>
      </Fragment>
    );
  }

  async handlePush(){
    const hash = await ipfsUtils.saveTextToIPFS(this.state.textInput);
    this.setState({textHash: hash});
  }

  async handlePull(){
    const text = await ipfsUtils.readTextFromIPFS(this.state.textHash);
    this.setState({textOutput: text});
  }

  handleInputChange(e){
    this.setState({textInput: e.target.value });
  }  
}

export default App;

这个示例把一串字符保存到IPFS,获得hash值;又通过hash值读取到这串字符。效果如下:

也可以在浏览器中读取这串字符:

关于如何把文件上传到IPFS和从IPFS的读取文件,这里由于篇幅所限,就不贴代码了。具体的代码可以到这里查看:


Tips

这里只是简单的演示如何使用ipfs-api,更多具体代码可以到Github查看:https://github.com/songguo6/eos-react-dapp

到这里,我们把文件保存到了IPFS上,并获得了一串哈希值。下一篇将学习,如何把这串哈希值存储到EOS区块链上。

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册