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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吾名招财

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值