7-4、5、6 react+ipfs上传文件数据及相关配置(react+区块链实战)

7-4、5、6 react+ipfs上传文件数据及相关配置(react+区块链实战)

7-4 react+ipfs上传文件

引入之前安装的ipfs-api
在这里插入图片描述

在电脑后台启动ipfs的服务
ipfs daemon(这个是go-api的不使用)
在这里插入图片描述

这里直接使用jsipfs进行后台服务启动
发现版本不兼容,之前还可以启动来,这估计是新安装ipfs-desktop导致的

jsipfs daemon(使用js的版本可以启动)

一个是0.8.0版本的

一个是0.6版本的

在这里插入图片描述

这里没有卸载ipfs桌面版,在重启电脑后启动jsipfs daemon就能打开js的ipfs服务了

在这里插入图片描述

在这里插入图片描述

如果出现了某个模块未安装的情景
在这里插入图片描述

关闭start

执行
Npm install

执行npm start后结果应如下

在这里插入图片描述

此处是上传文本的,也可以改成上传文件的按钮

在这里插入图片描述

文本上传之后会显示哈希值显示在页面

我们可以将文本读取
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

上方未做值的拼接先不用
显示不是一串字符故下方

使用下方
在这里插入图片描述

handleClick(){
console.log(this.state.text)
}

<input value={this.state.text} onChange={(e)=>{
this.setState(
{text:e.target.value}
)
}}/>
上方input将value输入的值保存到state状态中的text中,点击提交时,会调用打印
将状态state中的text打印出来如下

在这里插入图片描述

在这里插入图片描述

//将input中的内容保存到ipfs上
	saveTextToIpfs(text){
		//要将其转换成buffer上传
		const descBuf = Buffer.from(text,'utf-8')
			ipfs.add(descBuf).then(res=>{
				console.log(res)
			})
	}
	
	handleClick(){
		this.saveTextToIpfs(this.state.text)
		//console.log(this.state.text)	//打印保存到状态中的text值
	}

值浏览器刷新看到有报错(预料之中的报错,由于跨域导致的)
在这里插入图片描述

预料之中的报错,由于跨域导致的
第一个错误跨域导致的

第二个错误是逻辑问题
在这里插入图片描述

想向5001端口发送,但是我们现在的本地端口是在3000,需要在ipfs之上进行跨域配置(下节课讲)

本节所有代码

import React from 'react';
import ipfsAPI from 'ipfs-api';

let ipfs = ipfsAPI('localhost','5001',{protocol:'http'})	//本地启动服务默认5001端口

class App extends React.Component{

	constructor(propos){
		super(propos)
			//状态,上传内容,上传后的哈希
		this.state = {
			text : '', //保存上传的文本
			content:'',
			hash:''
		}
		//绑定按钮(否则会this穿透)
		this.handleClick = this.handleClick.bind(this)
		//this.handleReadClick = this.handleReadClick.bind(this) 若不想绑定可以使用下方的箭头函数,两种方式
	}

	//将input中的内容保存到ipfs上
	saveTextToIpfs(text){
		//要将其转换成buffer上传
		const descBuf = Buffer.from(text,'utf-8')
			ipfs.add(descBuf).then(res=>{
				console.log(res)
			})
	}
	
	handleClick(){
		this.saveTextToIpfs(this.state.text)
		//console.log(this.state.text)	//打印保存到状态中的text值
	}

	handleReadClick(){
	
	}

	//console.log(e.target.value)
	//e.target.value就是我们输入的值在input中
	render(){
		return(
			<div className='App'>
				<input value={this.state.text} onChange={(e)=>{
					this.setState(
						{text:e.target.value}
					)
				}}/>
				<button onClick={this.handleClick}>submit to ipfs</button>
				<hr/>
				<p>
					{this.state.hash}
				</p>
				<button onClick={()=>this.handleReadClick()}>read from ipfs</button>
				<p>
					{this.state.content}
				</p>
			</div>
		);
	
	}
}

export default App

7-5 react+ipfs 上传数据+ipfs跨域配置

之前提交数据发现会报错
在这里插入图片描述

实际上像ipfs接口请求数据并没有配置上

在jsipfs daemon启动后进行配置
在这里插入图片描述

如下
Jsipfs config show

在这里插入图片描述

可以看到所有api相关的配置,我们是没有header相关的配置的

在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”]’

https://www.cnblogs.com/yinian/p/9836853.html
注意:在window环境下,执行以上命令时可能报错,修改命令为:
jsipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods “[“PUT”, “POST”, “GET”, “OPTIONS”]”
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”]”

在cmd命令行输入上方的命令,不对加入
在这里插入图片描述

然后show可以看到如下
jsipfs config show
在这里插入图片描述

此时跨域配置成功
在展示config多出了API的数据

此时可以重新启动jsipfs daemon,再执行jsipfs config show依然存在
在这里插入图片描述

此时再输入123点击提交发现还是这个错误(因为端口冲突了5001)
在这里插入图片描述

找到App.js中
将5001的端口改成5002,本地的桌面版的端口与命令行版有冲突

在这里插入图片描述

在这里插入图片描述

修改代码只让其显示hash
在这里插入图片描述

在这里插入图片描述

将此hash值复制出来
QmYkMuFZj7tyHFJRVe7ucqMNYGEiSXrjKdudm2mu7UD7er

来到命令行中
jsipfs cat QmYkMuFZj7tyHFJRVe7ucqMNYGEiSXrjKdudm2mu7UD7er
在这里插入图片描述

就将值打印出来了

说明文本已经传递到ipfs上了

获取ipfs官网内容的规则
https://ipfs.io/ipfs/QmYkMuFZj7tyHFJRVe7ucqMNYGEiSXrjKdudm2mu7UD7er

如何访问ipfs的官网
https://blog.csdn.net/weixin_30852451/article/details/96953573
209.94.90.1 ipfs.io
更改hosts文件
注意不关机重启的话要刷新DNS在cmd下
ipconfig /flushdns

此时可以访问链接数据了如下
在这里插入图片描述

说明本地的ipfs同步到公网之上了

所有代码如下

import React from 'react';
import ipfsAPI from 'ipfs-api';

let ipfs = ipfsAPI('localhost','5002',{protocol:'http'})	//本地启动服务默认5001端口


class App extends React.Component{

	constructor(propos){
		super(propos)
			//状态,上传内容,上传后的哈希
		this.state = {
			text : '', //保存上传的文本
			content:'',
			hash:''
		}
		//绑定按钮(否则会this穿透)
		this.handleClick = this.handleClick.bind(this)
		//this.handleReadClick = this.handleReadClick.bind(this) 若不想绑定可以使用下方的箭头函数,两种方式
	}

	//将input中的内容保存到ipfs上
	saveTextToIpfs(text){
		//要将其转换成buffer上传
		const descBuf = Buffer.from(text,'utf-8')
			ipfs.add(descBuf).then(res=>{
				console.log(res[0].hash)
			})
	}
	
	handleClick(){
		this.saveTextToIpfs(this.state.text)
		//console.log(this.state.text)	//打印保存到状态中的text值
	}

	handleReadClick(){
	
	}

	//console.log(e.target.value)
	//e.target.value就是我们输入的值在input中
	render(){
		return(
			<div className='App'>
				<input value={this.state.text} onChange={(e)=>{
					this.setState(
						{text:e.target.value}
					)
				}}/>
				<button onClick={this.handleClick}>submit to ipfs</button>
				<hr/>
				<p>
					{this.state.hash}
				</p>
				<button onClick={()=>this.handleReadClick()}>read from ipfs</button>
				<p>
					{this.state.content}
				</p>
			</div>
		);
	
	}
}

export default App

7-6 react+ipfs读取ipfs网络数据

在上一章节的基础上

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

从ipfs读取数据

函数名和命令行基本一致
在这里插入图片描述

在这里插入图片描述

读取出来的是uint8的数组,完全可以将其转换成string类型的
https://blog.csdn.net/tsyx/article/details/79487645
上方必看
https://www.cnblogs.com/yinian/p/9836740.html

  ipfs.cat(this.state.hash).then((stream)=>{

                  console.log(stream);
                  var content=stream;
                  this.setState({content});
              });

这里不知为什么点击获取内容时失败报错如下

在这里插入图片描述

一直未找到问题,始终报错
尝试重新安装(可能是下载的ipfs-api不够完整)
Npm install
在这里插入图片描述

重新启动
Npm start

Jsipfs daemon

还是报错
在这里插入图片描述

上传成功后,可以在cmd jsipfs cat hash查看
但就是无法使用代码函数读取ipfs.cat
获取一个哈希值的文件内容失败

视频演示成功如下:
在这里插入图片描述

可以将uint8转换成string来展示

在这里插入图片描述

完整的效果如下
在这里插入图片描述

可以获取内容并显示到了界面

到公网查看数据,本地上传数据后和公网同步也是比较长时间的
在这里插入图片描述

命令行是可以读取的

下一章就是react+ipfs+在线教育

将文件上传到ipfs得到哈希值,将哈希值存到以太坊,再通过哈希值从ipfs将文件取出

该问题解决(无法读取ipfs中数据)
直接关闭jsipfs daemon命令行的启动(使用ipfs daemon启动之前的跨域配置此处也配置了)

桌面版自带ipfs的,尽管其使用go-ipfs的接口
但是当其启动后,本身5001的端口,APP.js的端口一改,再进行写入读取就没有错误了

原因很有可能是在windows使用的开启后的API端口和视频中不同后面多了个http
如下
在这里插入图片描述

HTTP API listening on /ip4/127.0.0.1/tcp/5002/http

而视频中的没有

在这里插入图片描述

解决方案直接启动ipfs daemon(下载的桌面版自带的即可)

在这里插入图片描述

再次将代码更改

在这里插入图片描述

运行成功后如下
在这里插入图片描述

已经得到uint8的字符了,此处需要将其转变为字符串

代码更改
在这里插入图片描述
在这里插入图片描述

所有的代码如下(确认成功运行):

import React from 'react';
import ipfsAPI from 'ipfs-api';

let ipfs = ipfsAPI('localhost','5001',{protocol:'http'})	//本地启动服务默认5001端口


class App extends React.Component{

	constructor(propos){
		super(propos)
			//状态,上传内容,上传后的哈希
		this.state = {
			text : '', //保存上传的文本
			content:'',
			hash:'',
		}
		//绑定按钮(否则会this穿透)
		this.handleClick = this.handleClick.bind(this)
		//this.handleReadClick = this.handleReadClick.bind(this) //若不想绑定可以使用下方的箭头函数,两种方式
	}

	//将input中的内容保存到ipfs上
	saveTextToIpfs(text){
		//要将其转换成buffer上传
		const descBuf = Buffer.from(text,'utf-8')
			ipfs.add(descBuf).then(res=>{
				//将获取到的hash放到当前状态state的hash中
				this.setState({
					hash:res[0].hash
				})
				//console.log(res[0].hash)
			})
	}
	
	handleClick(){
		this.saveTextToIpfs(this.state.text)
		//console.log(this.state.text)	//打印保存到状态中的text值
	}

	handleReadClick(){
		//console.log(this.state.hash)
		//下方代码有误,需测试
		ipfs.cat(this.state.hash).then(res=>{
			//console.log(res)
			let content = new TextDecoder('utf-8').decode(res)	//对uint8数组解码为字符串
			this.setState({
				content
			})
		})

	}

	//console.log(e.target.value)
	//e.target.value就是我们输入的值在input中
	render(){
		return(
			<div className='App'>
				<input value={this.state.text} onChange={(e)=>{
					this.setState(
						{text:e.target.value}
					)
				}}/>
				<button onClick={this.handleClick}>submit to ipfs</button>
				<hr/>
				<p>
					hash is : {this.state.hash}
				</p>
				<button onClick={()=>this.handleReadClick()}>read from ipfs</button>
				<p>
					{this.state.content}
				</p>
			</div>
		);
	
	}
}

export default App

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-14 06:12:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-14 06:12:01       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-14 06:12:01       58 阅读
  4. Python语言-面向对象

    2024-07-14 06:12:01       69 阅读

热门阅读

  1. 【代码复现】STAEformer

    2024-07-14 06:12:01       21 阅读
  2. python中的pickle模块和json模块

    2024-07-14 06:12:01       23 阅读
  3. ClickHouse实战第二章-ClickHouse 的安装调试

    2024-07-14 06:12:01       25 阅读
  4. Spring事件监听机制详解

    2024-07-14 06:12:01       22 阅读
  5. 案例:分库分表与SELECT * 发生的线上问题

    2024-07-14 06:12:01       24 阅读
  6. TypeScript的类型谓词与控制流分析

    2024-07-14 06:12:01       26 阅读
  7. ThreadLocal详解

    2024-07-14 06:12:01       22 阅读
  8. 小程序如何刷新当前页面

    2024-07-14 06:12:01       25 阅读
  9. qt 根据名称获取按钮,并添加点击事件

    2024-07-14 06:12:01       19 阅读
  10. Linux开发讲课37--- ARM的22个常用概念

    2024-07-14 06:12:01       27 阅读