使用Node.js为IPFS内容创建一个HTTP代理

702 阅读7分钟

在这篇文章中,我们将演示如何创建一个Node.js服务器,通过clearnet访问IPFS内容。在我们解释如何做到这一点之前,让我们先定义一下关键术语,并为为什么这很重要创造一些背景。

什么是clearnet?

信息网络本质上是可公开访问的互联网。它指的是使用所有浏览器支持的标准协议在公共网络上消费的所有网络内容,如HTTP、WebSocket(用于实时通信)和WebRTC(用于大多数音频和视频流平台)。

这些协议通常需要中央服务器和服务提供商来工作,这有可能成为把关的载体,特别是在对言论自由和隐私有限制的国家。

信息网络之外

还有一些其他非标准的网络协议,尽管它们可能不被所有的浏览器支持。例子包括。

  • 洋葱路由:一种在网络上实现匿名通信的技术,主要在Tor项目中实现
  • 双子座:一种通信协议,致力于成为Gopher和HTTP的替代品。有许多Gemini客户端可用
  • 星际文件系统(IPFS):一个用于共享数据的协议和点对点网络。流行的基于Chromium的Brave浏览器支持IPFS。

IPFS解释

与BitTorrent类似,IPFS是一个在分布式文件系统中存储和共享数据的协议。然而,关键的区别是,IPFS的目的是创建一个单一的全球网络。在IPFS中,被托管的单个文件被分配一个内容ID(CID),用来访问它。

为了说明其中的区别,在HTTP中,我们使用一个URI,如 [https://www.google.com](https://www.google.com),然后将其发送到DNS服务器。该服务器识别资源的IP地址并提供资源。然而,如果该主机被关闭或无法访问,该资源就会......消失。

在IPFS中,我们使用一个像ipfs://xjd9809bnuiue900sdfnuiwerwwer 的CID,它是通过网络中所有参与者托管的分布式哈希表(DHT)进行搜索来识别。我们不需要识别单一的资源提供者,而是识别所有拥有该资源副本的主机,并从所有这些主机中下载该资源的部分。

与任何互联网协议一样,IPFS的设计也有优点和缺点。

IPFS的优点

  • 一旦内容被添加到DHT中,只要有一台连接到IPFS网络的主机拥有该文件的副本,该文件就可以在网络上被访问。
  • 随着时间的推移,文件的可访问性会增加,因为每个访问该文件的用户都会成为另一个检索该文件的主机。
  • 没有任何外部实体可以单枪匹马地删除一个已经添加到网络中的文件。

IPFS的缺点

  • 当你最初向IPFS添加内容时,你是唯一的主机。因此,在一开始,可访问性是有限的
  • 你不能突变文件,所以如果你需要修复一个类型,你必须用一个新的CID添加一个新的文件副本,并提醒其他用户到新的CID去。
  • 目前不是所有的浏览器都支持

开始使用IPFS

让我们来安装IPFS CLI并向IPFS添加一些内容。在我们进行时,你可以参考IPFS文档

首先,安装IPFS。对于Linux和Mac,你可以使用brew install ipfs ,用Homebrew安装它。当它完成后,确保阅读输出的重要信息;对于Linux,它应该给你运行守护程序的确切路径。

一旦安装完毕,运行ipfs init ,并再次确保阅读输出中的一些重要细节--你可能想把它保存在安全的地方。输出应该共享一个cat命令来查看文档;运行该命令以确认一切都已设置好。

ipfs init 启动守护程序。要向IPFS添加文件,只需使用ipfs add FILENAME ,你就会收到CID。就这么简单!

消耗IPFS的内容

要消费IPFS的内容,只需在命令行中运行ipfs cat /ipfs/CONTENTID 来检索内容。

要通过浏览器消费IPFS内容,你需要使用Brave,它允许你查看IPFS的内容。在浏览器中,使用这个模式ipfs://CONTENTID 来访问内容。例如,这里有一个我发布到IPFS的 "Hello, World!"文本文件的链接:ipfs://QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u

通过HTTP传递IPFS内容

IPFS是非常酷的,但大多数日常的互联网用户并不想下载一个替代的浏览器或使用CLI工具来浏览网络上的资源。因此,也许你想通过创建一个代理应用程序,在主流浏览器中获取内容,将你的IPFS内容传递给清网用户。让我们用Node.js来做这件事。

注意,这个演示应用程序必须在一台同时运行IPFS服务器的机器上运行。这意味着你要使用虚拟专用服务器(VPS)进行部署,在那里你可以在你的Node.js应用程序上并行运行IPFS服务器。

设置应用程序

首先创建一个新的文件夹,并将目录改到该文件夹。通过运行touch server.js ,创建一个server.js 文件,然后用npm init -y 启动一个新的Node.js项目。最后,通过运行npm install fastify ipfs-http-client ,安装Fastify(尽管任何Web框架都可以)和ipfs-http-client。

让Node服务器运行

在你的server.js 文件中添加以下代码。

// import fastify
const fastify = require("fastify");

// create the server object
const server = fastify({ logger: true });

// example route
server.get("/", async (request, reply) => {
  return { message: "The Server is Working" };
});

// start server function
const start = async () => {
  await server.listen(3000).catch((err) => {
    fastify.log.error(err);
    process.exit(1);
  });
  console.log("Listening on port 3000")
};

// turn server on
start();

运行文件node server.js ,在浏览器中进入localhost:3000 ,并确保你看到了这个信息。在终端中用Control+C 关闭服务器。

[H3] 使用ipfs-http-client

我们需要将我们的server.js 更新为下面的代码,但首先让我们走一遍我们正在做的事情。

首先,我们将导入ipfs-http-client库作为ipfs 。然后我们创建一个连接到localhost:5001 的客户端,这是我们本地IPFS服务器应该运行的默认端口。

我们使用客户端的get 方法来获取数据的CID。该函数返回一个包裹在AsyncGenerator 中的字节的Uint8Array (有趣!)。

我们使用一个for await 循环来循环生成器,然后使用一个文本编码器将字节数组解码成一个字符串。循环结束后,生成的文本中有几个空字符,所以我们用string.replace 删除它们。最后,我们将生成的字符串作为JSON发送回去。

// import fastify
const fastify = require("fastify");
// import ipfs-http-client
const ipfs = require("ipfs-http-client")

// connect to local ipfs node
const client = ipfs.create()

// create the server object
const server = fastify({ logger: true });

// example route
server.get("/", async (request, reply) => {

  // fetch the content from ipfs
  const result = await client.get("QmWATWQ7fVPP2EFGu71UkfnqhYXDYH566qy47CnJDgvs8u")

  // create a string to append contents to
  let contents = ""


  // loop over incoming data
  for await(const item of result){
      // turn string buffer to string and append to contents
      contents += new TextDecoder().decode(item)
  }

  // remove null characters
  contents = contents.replace(/\0/g, "")

  // return results as a json
  return { message: contents };
});

// start server function
const start = async () => {
  await server.listen(3000).catch((err) => {
    fastify.log.error(err);
    process.exit(1);
  });
  console.log("Listening on port 3000")
};

// turn server on
start();

请注意,结果并不是世界上最友好的。结果字符串包括CID和一个时间戳;换句话说,附加信息与我的 "Hello, World!"文件的内容一起。如果这是一个HTML文件,我可能要做一些额外的清理工作来删除所有非HTML的内容,但至少我们得到了内容。

所以,从理论上讲,我们可以把这个应用托管在一个也安装了IPFS的VPS上,在clearnet/HTTP上的用户可以看到我们的内容,而不需要下载一个特殊的浏览器或命令行工具。

总结

IPFS提出了一些非常有趣的想法,即互联网如何能够更加分散和自由,但它确实以牺牲一些便利为代价。然而,通过巧妙地使用Node.js,我们可以开始为大众弥补这一差距。

The postUsing Node.js to create an HTTP proxy for IPFS contentappeared first onLogRocket Blog.