微信小程序通过ipfs-api 实现图片文件在私有ipfs网络的上传与下载显示

1.快速搭建IPFS私有网络(docker)

拉取镜像

docker pull docker.io/ipfs/go-ipfs:latest

编写yaml文件

创建两个文件夹并分别命名为:ipfs_node1和ipfs_node2,用于启动ipfs两节点(可多机)。分别进入对应文件夹创建并编写yaml文件:

mkdir ipfs_node1 ipfs_node2
cd ipfs_node1
vim docker-compose.yaml
version: "3"

services:

  ipfs_host:
    container_name: ipfs_host
    image: docker.io/ipfs/go-ipfs:latest
    restart: always
    volumes:
      - ./staging:/export
      - ./data:/data/ipfs
    ports:
      - 4001:4001
      - 0.0.0.0:8080:8080
      - 0.0.0.0:5001:5001

默认挂载目录为项目目录下的 datastaging 文件夹,可根据实际情况修改。同理创建并添加ipfs_node2文件夹yaml文件。

cd ipfs_node2
vim docker-compose.yaml
version: "3"

services:

  ipfs_host2:
    container_name: ipfs_host2
    image: docker.io/ipfs/go-ipfs:latest
    restart: always
    volumes:
      - ./staging:/export
      - ./data:/data/ipfs
    ports:
      - 4002:4001
      - 0.0.0.0:8082:8080
      - 0.0.0.0:5002:5001

启动docker

cd ipfs_node1
docker-compose up -d
cd ipfs_node2
docker-compose up -d

docker启动会自动创建data和staging目录。
image

确保配置 IPFS API 以允许跨源(CORS)请求

配置跨源方便后面的ipfs-api进行get,post等请求使用。

docker exec ipfs_host ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'

docker exec ipfs_host ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]'

docker exec ipfs_host2 ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'

docker exec ipfs_host2 ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]'

生成共享key并分发

go get -u github.com/Kubuxu/go-ipfs-swarm-key-gen/ipfs-swarm-key-gen
ipfs-swarm-key-gen > swarm.key

要将产生的key复制到两个文件夹的data目录下,且保证两个key是一致的。

移除默认的 boostrap 节点

IPFS 默认是通过一些种子连接到全球网络,但是我们现在是要搭建私有网络,所以需要先把种子节点连接信息删除。

docker exec ipfs_host ipfs bootstrap rm --all
docker exec ipfs_host2 ipfs bootstrap rm --all

建立两节点之间的连接

使用ipfs id命令查看节点id,用于添加节点。

docker exec ipfs_host ipfs id

image
第二节点使用第一节点ip地址以及id添加对方节点。

docker exec ipfs_host2 ipfs bootstrap add /ip4/192.168.177.130/tcp/4001/ipfs/12D3KooWKJE5cw7N8Arq8mhEMPupxXCuh6Xn6yfHBLWrrcTASqQf

按照上述步骤查看第二节点id并通过第一节点添加。

重启docker服务并查看各自邻居

重启服务
docker restart ipfs_host
docker restart ipfs_host2
查看邻居
docker exec ipfs_host ipfs swarm peers

image

docker exec ipfs_host2 ipfs swarm peers

image

添加测试文件

上述过程没报错误则搭建基本完成,简单测试一下。

cd /data
echo 888 >> test.txt

添加一个txt文件内容为888,现在把它上传。
docker exec ipfs_host2 ipfs add /data/ipfs/test.txt
image
通过节点1的ipfs cat 查看改hash下的文件

docker exec ipfs_host1 ipfs cat QmVNSG4XiBovJT1vSmK8tJV5zsT2Xz3gy9C3bRXhCp95up

image
完成以上步骤就可以进行api的调试了。

2.调试IPFS-API

调试IPFS使用的是postman,请求地址格式为http://localhsot(节点ip地址)/ports/api/版本默认v0/命令语句,比如使用查看相邻节点命令是 swarm peers,则请求地址为:
http://192.168.177.130:5001/api/v0/swarm/peers
image
得到连接节点的id等信息。

上传文件、浏览文件测试

ipfs 上传文件的命令为 add <文件path路径>,api则需要使用post请求且body设置from-data格式,然后通过key-文件value的形式上传文件。
image
上传成功可得到用于获取文件的hash,使用该hash可对文件进行预览、下载和保存。
image.png
通过http://192.168.177.130:8080/ipfs/hash 可对上传的图片进行预览。
image

3.小程序界面设计

前面postman测试通过就可以进行小程序端设计了,设计的主要思路是点击上传按钮上传本地图片到ipfs,点击下载按钮,使用已上传的hash获取该图片并显示出来。

Wxml

image
效果展示图如下:
image

4.js部分

照片上传部分

首先调用chooseImag函数获取到用户上传图片的路径,然后调用uploadFile上传图片文件到ipfs。通过success回调函数保存hash值用于文件的下载以及预览。

    chooseImg: function (e) {
      var that = this;
      var imgs = this.data.imgs;
      wx.chooseImage({
        // count: 1, // 默认9
        sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
        sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
        success: function (res) {
              const tempFilePaths = res.tempFilePaths
              wx.uploadFile({
                url: 'http://192.168.177.130:5001/api/v0/add', //仅为示例,非真实的接口地址
                filePath: res.tempFilePaths[0],  
                name: 'file',
                formData: {
  
                },
                success (res){
                  console.log(JSON.parse(res.data).Hash)
                 var a = JSON.parse(res.data).Hash
                  that.setData({
                   hashcode : a
                 })
                }
              })
        }
      });
    },
照片下载预览部分

使用downloadFile函数下载文件并获取保存路径,将文件setdata给images变量,并显示到前端。

    xiazai:function(){
      var that =this
        var hashcode = that.data.hashcode
          wx.downloadFile({
            url: 'http://192.168.177.130:8080/ipfs/'+hashcode,
            success (res) {
             console.log(res)
              if (res.statusCode === 200) {
                wx.playVoice({
                  filePath: res.tempFilePath
                })
                console.log(res.tempFilePath)
                that.setData({
                  images:res.tempFilePath
                })
              }
            }
          })

    }

5.效果展示

上传图片文件

文件上传成功返回文件hash值
image

下载并显示文件

image.png
image.png