如何使用 Node.js 将文件上传到对象存储中

介绍

对象存储是存储和服务静态资产(如音频、图像、文本、PDF 和其他类型的非结构化数据)的流行的可扩展方法。云提供商除了传统的本地或区块存储之外,还提供对象存储,用于存储动态应用程序文件和数据库。

Spaces是DigitalOcean提供的简单的对象存储服务,除了能够通过控制面板登录、上传、管理和删除存储的文件外,您还可以通过命令行和Spaces API访问您的DigitalOcean Space。

在本教程中,我们将创建一个Node.js应用程序,允许用户通过在网站的前端提交表单将文件上传到他们的DigitalOcean Space。

前提条件

要跟随这个教程,你需要:

  • 一个数字海洋空间,以及一个访问密钥和你的帐户的秘密访问密钥。阅读 如何创建数字海洋空间和API密钥以使用数字海洋帐户运行,创建一个空间,并设置一个API密钥和秘密
  • Node.js 和 npm 安装在你的计算机上。你可以访问 Node.js 下载以安装操作系统的正确版本。

您现在应该有一个DigitalOcean帐户,一个具有访问密钥的空间,以及安装在您的计算机上的Node.js和npm。

添加访问密钥到凭证文件

DigitalOcean Spaces 与 Amazon Simple Storage Service (S3) API 兼容,我们将使用 AWS SDK for JavaScript in Node.js 连接到我们创建的空间。

第一步是创建一个 credentials文件,将您在创建您的 DigitalOcean Space 时获得的访问密钥和秘密访问密钥放置在位置上。 该文件将在 Mac 和 Linux 上位于 ~/.aws/credentials,或者在 Windows 上位于 C:\Users\USERNAME\.aws\credentials

打开命令提示,确保你在你的 用户目录中,可以访问一个管理sudo用户,并创建一个 **.aws**目录,里面有 **credentials**文件。

1sudo mkdir .aws && touch .aws/credentials

打开文件,并插入以下代码,以您的各自密钥代替your_access_keyyour_secret_key

1[label credentials]
2[default]
3aws_access_key_id=your_access_key
4aws_secret_access_key=your_secret_key

现在,您通过 AWS SDK 访问 Spaces 将被验证,我们可以继续创建应用程序。

安装 Node.js 依赖

首先,创建一个目录,你想把你的 Node.js 应用程序放在其中,然后导航到目录. 为此演示,我们将创建我们的项目在 **spaces-node-app**中的 **sites**目录。

1mkdir sites/spaces-node-app && cd sites/spaces-node-app

为您的项目创建一个新的 package.json 文件. 将下面的代码粘贴到文件中。

 1[label package.json]
 2{
 3  "name": "spaces-node-app",
 4  "version": "1.0.0",
 5  "main": "server.js",
 6  "scripts": {
 7    "start": "node server.js"
 8  },
 9  "license": "MIT"
10}

這是一個基本的「package.json」檔案,列出我們應用程式的名稱、版本號碼和許可證. 「scripts」字段將允許我們通過輸入「npm start」而不是「node server.js」來執行 Node.js 伺服器。

我们将使用npm install命令安装所有依赖,然后是我们项目中的四个依赖的名称。

1npm install aws-sdk express multer multer-s3

运行此命令后,应该更新package.json文件,这些依赖将帮助我们连接到DigitalOcean Spaces API,创建Web服务器,并处理文件上传。

  • aws-sdk — AWS SDK for JavaScript将允许我们通过JavaScript API访问S3
  • express — Express是一个网络框架,可以让我们快速有效地设置服务器
  • multer — Multer是处理文件上传的中间软件
  • multer-s3 — Multer S3将文件上传扩展到S3对象存储,在我们的情况下,DigitalOcean Spaces_( )

现在我们已经设置了项目位置和依赖性,我们可以设置服务器和前端视图。

<$>[注] 注: npm install 默认情况下在当前版本的 Node 中将依赖性保存到 package.json 文件中。

创建应用程序的前端

首先,让我们为我们的应用程序的公共视图创建文件,这是用户将在前端看到的。在您的项目中创建一个 公共目录,其中包括 index.html, success.htmlerror.html. 这些文件中的三个都将有下面的HTML骨骼,在 body中有不同的内容。

 1<!DOCTYPE html>
 2<html lang="en">
 3
 4<head>
 5  <meta charset="utf-8">
 6  <meta name="viewport" content="width=device-width, initial-scale=1.0">
 7
 8  <title>DigitalOcean Spaces Tutorial</title>
 9
10  <link rel="stylesheet" href="./style.css">
11</head>
12
13<body>
14
15  <!-- contents will go here -->
16
17</body>
18
19</html>

Error.html中写一个错误消息。

1[label error.html]
2...
3
4<h1>Something went wrong!</h1>
5<p>File was not uploaded successfully.</p>
6
7...

success.html身体中写一个成功消息。

1[label success.html]
2...
3
4<h1>Success!</h1>
5<p>File uploaded successfully.</p>
6
7...

在index.html中,我们将创建一个HTML表格,包含多部分/表格数据,由一个简单的文件上传输入和提交按钮组成。

 1[label index.html]
 2...
 3
 4<h1>DigitalOcean Spaces Tutorial</h1>
 5
 6<p>Please select a file and submit the form to upload an asset to your DigitalOcean Space.</p>
 7
 8<form method="post" enctype="multipart/form-data" action="/upload">
 9  <label for="file">Upload a file</label>
10  <input type="file" name="upload">
11  <input type="submit" class="button">
12</form>
13
14...

最后,让我们创建style.css,并添加足够的CSS来使应用程序易于阅读。

 1[label style.css]
 2html {
 3  font-family: sans-serif;
 4  line-height: 1.5;
 5  color: #333;
 6}
 7
 8body {
 9  margin: 0 auto;
10  max-width: 500px;
11}
12
13label,
14input {
15  display: block;
16  margin: 5px 0;
17}

有了这三个文件,我们有一个上传表格,构成我们的小应用程序的主页,我们有成功和错误页面为用户。

创建 Express Server 环境

我们已经为我们的应用程序的前端创建了所有文件,但我们目前没有服务器设置或任何方式来查看它们。

在项目的根目录中,创建一个 server.js 文件. 在顶部,加载我们的四个依赖性与 require(). 我们将路由我们的应用程序通过 app 实例的 express

1[label server.js]
2// Load dependencies
3const aws = require('aws-sdk');
4const express = require('express');
5const multer = require('multer');
6const multerS3 = require('multer-s3');
7
8const app = express();

我们的前端位于公共目录中,因此将该配置设置在依赖性下方。

1[label server.js]
2...
3
4// Views in public directory
5app.use(express.static('public'));

我们将路由index.html,success.htmlerror.html相对于服务器的根。

 1[label server.js]
 2...
 3
 4// Main, error and success views
 5app.get('/', function (request, response) {
 6  response.sendFile(__dirname + '/public/index.html');
 7});
 8
 9app.get("/success", function (request, response) {
10  response.sendFile(__dirname + '/public/success.html');
11});
12
13app.get("/error", function (request, response) {
14  response.sendFile(__dirname + '/public/error.html');
15});

最后,我们会告诉服务器听哪个端口. 在本示例中,使用3001,但您可以将其设置为任何可用的端口。

1[label server.js]
2...
3
4app.listen(3001, function () {
5  console.log('Server listening on port 3001.');
6});

保存server.js并启动服务器. 您可以通过运行node server.js,或使用npm start,我们在package.json中设置的捷径。

1npm start
1[secondary_label Output]
2> node server.js
3
4Server listening on port 3001.

导航到http://localhost:3001,你会看到上传表单,因为我们将index.html设置为服务器的根。

DigitalOcean Spaces Node.js Upload Form

您还可以导航到http://localhost:3001/successhttp://localhost:3001/error,以确保这些页面正确地路由。

将文件上传到 Multer 的空间

现在我们的服务器环境已经正常运行,最后一步是将表单与Multer和Multer S3集成,以将文件上传到Spaces。

您可以使用 new aws.S3() 连接到 Amazon S3 客户端。 对于使用 DigitalOcean Spaces,我们需要设置一个新的终端点,以确保它上传到正确的位置。

server.js中,向上滚动,并将下面的代码粘贴在恒定声明下方。

1[label server.js]
2...
3const app = express();
4
5// Set S3 endpoint to DigitalOcean Spaces
6const spacesEndpoint = new aws.Endpoint('nyc3.digitaloceanspaces.com');
7const s3 = new aws.S3({
8  endpoint: spacesEndpoint
9});

使用 multer-s3文档的示例,我们将创建一个上传函数,将属性设置为您的独特空间名称。

 1[label server.js]
 2...
 3
 4// Change bucket property to your Space name
 5const upload = multer({
 6  storage: multerS3({
 7    s3: s3,
 8    bucket: 'your-space-here',
 9    acl: 'public-read',
10    key: function (request, file, cb) {
11      console.log(file);
12      cb(null, file.originalname);
13    }
14  })
15}).array('upload', 1);

上传功能已经完成,我们的最后一步是将上传表单与代码连接起来,以便通过发送文件并相应地路由用户。

 1[label server.js]
 2...
 3app.post('/upload', function (request, response, next) {
 4  upload(request, response, function (error) {
 5    if (error) {
 6      console.log(error);
 7      return response.redirect("/error");
 8    }
 9    console.log('File uploaded successfully.');
10    response.redirect("/success");
11  });
12});

当用户点击提交时,一个 POST 请求会传到 /upload. Node 正在听取此 POST,并调用 upload() 函数. 如果发现了错误,条件声明会将用户重定向到 /error 页面.如果成功通过,用户将被重定向到 /success 页面,并将文件上传到您的空间。

这里是server.js的完整代码。

 1[label server.js]
 2// Load dependencies
 3const aws = require('aws-sdk');
 4const express = require('express');
 5const multer = require('multer');
 6const multerS3 = require('multer-s3');
 7
 8const app = express();
 9
10// Set S3 endpoint to DigitalOcean Spaces
11const spacesEndpoint = new aws.Endpoint('nyc3.digitaloceanspaces.com');
12const s3 = new aws.S3({
13  endpoint: spacesEndpoint
14});
15
16// Change bucket property to your Space name
17const upload = multer({
18  storage: multerS3({
19    s3: s3,
20    bucket: 'your-space-here',
21    acl: 'public-read',
22    key: function (request, file, cb) {
23      console.log(file);
24      cb(null, file.originalname);
25    }
26  })
27}).array('upload', 1);
28
29// Views in public directory
30app.use(express.static('public'));
31
32// Main, error and success views
33app.get('/', function (request, response) {
34  response.sendFile(__dirname + '/public/index.html');
35});
36
37app.get("/success", function (request, response) {
38  response.sendFile(__dirname + '/public/success.html');
39});
40
41app.get("/error", function (request, response) {
42  response.sendFile(__dirname + '/public/error.html');
43});
44
45app.post('/upload', function (request, response, next) {
46  upload(request, response, function (error) {
47    if (error) {
48      console.log(error);
49      return response.redirect("/error");
50    }
51    console.log('File uploaded successfully.');
52    response.redirect("/success");
53  });
54});
55
56app.listen(3001, function () {
57  console.log('Server listening on port 3001.');
58});

停止 Node 服务器,在命令提示中键入CONTROL +C,然后重新启动,以确保新的更改被应用。

1npm start

导航到项目的根,选择一个文件,并提交表单. 如果一切都设置正确,你将被重定向到成功页面,一个公共文件将在你的DigitalOcean空间。

Success confirmation page following upload

假设您上传的文件是 test.txt,该文件的URL将是 https://your-space-here.nyc3.digitaloceanspaces.com/test.txt

失败交易的常见原因可能是错误的凭证、错误的位置上的凭证文件或错误的桶名称。

结论

恭喜您,您已经设置了一个 Node.js 和 Express 应用程序来上传静态资产到对象存储!

您可以使用这个DigitalOcean Spaces Node应用程序的代码来玩游戏,通过此处重新混合项目(https://glitch.com/edit/#!/spaces-node-app?path=README.md:1:0)。

必须采取其他预防措施,例如验证,以便将此类应用程序投入生产,但这是一个良好的起点,以使您的Web应用程序与DigitalOcean Spaces功能。

Published At
Categories with 技术
comments powered by Disqus