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

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

  • 7-4 react+ipfs上传文件
  • 7-5 react+ipfs 上传数据+ipfs跨域配置
  • 7-6 react+ipfs读取ipfs网络数据

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/797243.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VSCode remote无法链接

报错信息如下&#xff1a; 远程主机密钥变化导致验证失败 无法连接 解决措施&#xff1a; 删除C:\Users\username.ssh\known_hosts中旧的主机密钥条目&#xff0c;重新连接

载波相位定位原理

在现代定位系统中&#xff0c;载波相位测距技术因其高精度而备受青睐。本文将探讨其工作原理&#xff0c;以及如何通过数学模型和算法来校正测量中的误差。 载波相位测距模型 载波相位测距是基于接收卫星发射的载波信号相位变化来进行距离测量的技术。它利用了信号传输过程中…

无障碍全免费上手智能体:Autogen Studio结合Deepseek Coder打造一款AI旅游规划师

本文的唯一目的是通过打造一款AI旅游规划师&#xff0c;通俗易懂、深入浅出的讲清楚AI应用的大方向-智能体-的原理。 无需科学上网&#xff0c;无需付费API&#xff0c;无需编程能力&#xff0c;一小时即可部署、搭建一款复杂的、多代理交互的AI智能体-旅游规划师&#xff0c;…

【C++初阶】类和对象(中)

【C初阶】类和对象&#xff08;中&#xff09; &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C&#x1f96d; &#x1f33c;文章目录&#x1f33c; 1. 类的6个默认成员函数 2. 构造函数 2.1 构造函数概念 2.2 构造函数的特性 3. 析…

pytorch说明

深度学习中的重要概念&#xff1a; 激活函数&#xff1a; 激活函数的必要性&#xff1a;激活函数不是绝对必须的&#xff0c;但在深度学习中&#xff0c;它们几乎总是被使用。激活函数可以引入非线性&#xff0c;这使得神经网络能够学习更复杂的模式。 激活函数的位置&#x…

阿里云产品流转

本文主要记述如何使用阿里云对数据进行流转&#xff0c;这里只是以topic流转&#xff08;再发布&#xff09;为例进行说明&#xff0c;可能还会有其他类型的流转&#xff0c;不同服务器的流转也可能会不一样&#xff0c;但应该大致相同。 1 创建设备 具体细节可看&#xff1a;…

免费的AI抠图工具 毫秒级抠图 离线可用 -鲜艺AI抠图

鲜艺AI抠图是一款免费的AI抠图工具&#xff0c;不登录、不联网&#xff0c;内嵌 AI 模型&#xff0c;快至毫秒级抠图&#xff0c;支持批量抠图&#xff0c;支持点击按钮选择图片、拖入图片、粘贴图片、粘贴图片链接、从网页拖入图片&#xff0c;支持Windows和macos&#xff0c;…

Vue el-input 限制输入内容

&#x1f914;日常项目中经常遇到既要el-input的样式&#xff0c;又要el-input-number限制&#xff0c;所以需要绑定input事件进行约束输入限制。 以下使用自定义指令进行约束el-input输入的值&#xff0c;便于后期统一管理和拓展。 预览 代码 <!DOCTYPE html> <ht…

使用 NumPy 及其相关库(如 pandas、scikit-learn 等)时,由于 NumPy 的版本不兼容或者某些依赖库与 NumPy 的版本不匹配

题意&#xff1a; numpy.dtype size changed, may indicate binary incompatibility. Expected 96 from C header, got 88 from PyObject 问题背景&#xff1a; I want to call my Python module from the Matlab. I received the error: Error using numpy_ops>init thi…

Go 初始化一个字典value是列表

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

react的解构赋值

我最近在用react讨生活。我的感觉&#xff0c;react开发效率不高。这当然应该是我还不熟悉react的缘故。但是&#xff0c;在阅读react代码过程中&#xff0c;其中一个容易困惑的地方是它到处充斥着的解构赋值。当然了&#xff0c;解构赋值并不是React特有的功能&#xff0c;而是…

秋招Java后端开发冲刺——MyBatisPlus总结

一、 基本知识 1. 介绍 yBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上增加了大量功能和简化操作&#xff0c;以提高开发效率。 2. 特点 无侵入&#xff1a;只做增强不做改变&#xff0c;引入它不会对现有项目产生影响。依赖少&#xff1a;仅仅依赖 …

【VS2019】安装下载库HtmlAgilityPack,可解析 HTML (图文详情)

目录 0.背景 1.环境 2.详细步骤 0.背景 项目需要&#xff0c;搭建WCF服务&#xff0c;需求是输入一个string类型字符串&#xff08;网页代码&#xff0c;如<html><body><p>Hello, <b>World</b>!</p></body></html>&#xf…

华为配置蓝牙终端定位实验

个人主页&#xff1a;知孤云出岫 目录 配置蓝牙终端定位示例 业务需求 组网需求 数据规划 配置思路 配置注意事项 操作步骤 配置文件 配置蓝牙终端定位示例 组网图形 图1 配置蓝牙终端定位示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业…

NAT地址转换+多出口智能选路,附加实验内容

本章主要讲&#xff1a;基于目标IP、双向地址的转换 注意&#xff1a;基于目标NAT进行转换 ---基于目标IP进行地址转换一般是应用在服务器端口映射&#xff1b; NAT的基础知识 1、服务器映射 服务器映射是基于目标端口进行转换&#xff0c;同时端口号也可以进行修改&…

力扣每日一题:3011. 判断一个数组是否可以变为有序

力扣官网&#xff1a;前往作答&#xff01;&#xff01;&#xff01;&#xff01; 今日份每日一题&#xff1a; 题目要求&#xff1a; 给你一个下标从 0 开始且全是 正 整数的数组 nums 。 一次 操作 中&#xff0c;如果两个 相邻 元素在二进制下数位为 1 的数目 相同 &…

Manim的代码练习02:在manim中Dot ,Arrow和NumberPlane对象的使用

Dot&#xff1a;指代点对象或者表示点的符号。Arrow&#xff1a;指代箭头对象&#xff0c;包括直线上的箭头或者向量箭头等。NumberPlane&#xff1a;指代数轴平面对象&#xff0c;在Manim中用来创建包含坐标轴的数学坐标系平面。Text&#xff1a;指代文本对象&#xff0c;用来…

WEB前端02-HTML5基础(02)

7.表格标签 在基本表格结构中&#xff0c;表格标题、项目表头和数据资料构成了表格基本结构三个要素。 table标签&#xff1a;定义表格整体 <caption>我的标题</caption>&#xff1a;表格的标题tr标签&#xff1a;定义表格的行 height&#xff1a;设置行的高度…

探索 Prompt 的世界:让你的 AI 更智能

探索 Prompt 的世界&#xff1a;让你的 AI 更智能 引言什么是 Prompt&#xff1f;Prompt 的重要性如何编写有效的 Prompt1. 清晰明确2. 包含关键细节3. 提供上下文 实践中的 Prompt 技巧1. 多次迭代2. 实验不同风格3. 结合实际应用 总结 引言 随着人工智能&#xff08;AI&…

卸载wps office的几种方法收录

​ 第一种方法: 1.打开【任务管理器】&#xff0c;找到相关程序&#xff0c;点击【结束任务】。任务管理器可以通过左下角搜索找到。 2.点击【开始】&#xff0d;【设置】&#xff0d;【应用】&#xff0d;下拉找到WPS应用&#xff0c;右键卸载&#xff0c;不保留软件配置 …