gpt4 book ai didi

node.js - 上传图片 - Nodejs Paperclip 和 S3

转载 作者:搜寻专家 更新时间:2023-10-31 22:21:01 28 4
gpt4 key购买 nike

我想使用 NodeJS 将图像上传到 S3 并保存到用户记录,就像 Rails Paperclip gem 一样。

我相信这应该是这个过程,但我还是很困惑这个包应该如何工作:

  1. 接收图像并通过回形针调整大小
  2. 保存或更新到 S3
  3. 将文件保存到数据库中的用户

我有一个 Rails Postgres 数据库,用户可以上传图像,存储在 S3 中,并使用 Paperclip gem 重新格式化。这是它的存储方式:

irb(main):003:0> user.avatar
=> #<Paperclip::Attachment:0x000055b3e043aa50 @name=:avatar,
@name_string="avatar", @instance=#<User id: 1, email:
"example@gmail.com", created_at: "2016-06-11 22:52:36",
updated_at: "2019-06-16 17:17:16", first_name: "Clarissa",
last_name: "Jones", avatar_file_name: "two_people_talking.gif",
avatar_content_type: "image/gif", avatar_file_size: 373197,
avatar_updated_at: "2019-06-16 17:17:12", @options={:convert_options=>{},
:default_style=>:original, :default_url=>":style/missing.png",
:escape_url=>true, :restricted_characters=>/[&$+,\/:;=?@<>\[\]\
{\}\|\\\^~%# ]/, :filename_cleaner=>nil,
:hash_data=>":class/:attachment/:id/:style/:updated_at",
:hash_digest=>"SHA1", :interpolator=>Paperclip::Interpolations,
:only_process=>[],
:path=>"/:class/:attachment/:id_partition/:style/:filename",
:preserve_files=>false, :processors=>[:thumbnail],
:source_file_options=>{:all=>"-auto-orient"}, :storage=>:s3,
:styles=>{:large=>"500x500#", :medium=>"200x200#",
:thumb=>"100x100#"}, :url=>":s3_path_url",
:url_generator=>Paperclip::UrlGenerator,
:use_default_time_zone=>true, :use_timestamp=>true, :whiny=>true,
:validate_media_type=>true, :adapter_options=>
{:hash_digest=>Digest::MD5},
:check_validity_before_processing=>true, :s3_host_name=>"s3-us-
west-2.amazonaws.com", :s3_protocol=>"https", :s3_credentials=>
{:bucket=>"example", :access_key_id=>"REDACTED",
:secret_access_key=>"REDACTED",
:s3_region=>"us-west-2"}}, @post_processing=true,
@queued_for_delete=[], @queued_for_write={}, @errors={},
@dirty=false, @interpolator=Paperclip::Interpolations,
@url_generator=#<Paperclip::UrlGenerator:0x000055b3e043a8e8
@attachment=#<Paperclip::Attachment:0x000055b3e043aa50 ...>>,
@source_file_options={:all=>"-auto-orient"}, @whiny=true,
@s3_options={}, @s3_permissions={:default=>:"public-read"},
@s3_protocol="https", @s3_metadata={}, @s3_headers={},
@s3_storage_class={:default=>nil},
@s3_server_side_encryption=false, @http_proxy=nil,
@use_accelerate_endpoint=nil>

user.avatar(:thumb) 返回:

https://s3-us-west-2.amazonaws.com/example/users/avatars/000/000/001/thumb/two_people_talking.gif?1560705432

现在,我正在尝试让用户通过 react-native 应用程序上传新的/更改的图像,而后端是 Nodejs,这对我来说是比较新的。

我对如何实现它感到很困惑,尤其是因为示例都引用了我没有使用的 Mongoose。

为了展示我是如何成功更新用户的,下面是如何更新用户的 first_name:

users.updateUserPhoto = (req, res) => {

let id = req.decoded.id
let first_name = req.body.first_name

models.Users.update(
first_name: first_name,
{
where: {
id: req.decoded.id
}
},
).then(response => {
res.status(200).json({ status: 200, data: { response } });
})
.catch(error => {
res.status(500).json({ status: 500, err: error });
})
}

这是我找到的包 node-paperclip-s3 ,这就是我正在尝试做的事情:

'use strict'
let users = {};
const { Users } = require('../models');
let models = require("../models/index");

let Sequelize = require('sequelize');
let Paperclip = require('node-paperclip');
let Op = Sequelize.Op;
let sequelizeDB = require('../modules/Sequelize');

users.updateUserPhoto = (req, res) => {
let id = req.decoded.id
let avatar = req.body.avatar <- this is a file path

models.Users.plugin(Paperclip.plugins, {
avatar: {
styles: [
{ original: true },
{ large: { width: 500, height: 500 } },
{ medium: { width: 200, height: 200 } },
{ thumb: { width: 100, height: 100 } }
],
prefix: '/users/{{attachment}}/{{id}}/{{filename}}',
name_format: '{{style}}.{{extension}}',
storage: 's3',
s3: {
bucket: process.env.S3_BUCKET_NAME,
region: 'us-west-2',
key: process.env.AWS_ACCESS_KEY_ID,
secret: process.env.AWS_SECRET_ACCESS_KEY,
}
}
})

models.Users.update(
avatar,
{
where: {
id: req.decoded.id
}
},
).then(response => {
res.status(200).json({ status: 200, data: { response } });
})
.catch(error => {
res.status(500).json({ status: 500, err: error });
})
}

我也试过这样的:

    models.Users.update(Paperclip.plugins, {
avatar: {
styles: [
{ original: true },
{ large: { width: 500, height: 500 } },
{ medium: { width: 200, height: 200 } },
{ thumb: { width: 100, height: 100 } }
],
prefix: '/users/{{attachment}}/{{id}}/{{filename}}',
name_format: '{{style}}.{{extension}}',
storage: 's3',
s3: {
bucket: process.env.S3_BUCKET_NAME,
region: 'us-west-2',
key: process.env.AWS_ACCESS_KEY_ID,
secret: process.env.AWS_SECRET_ACCESS_KEY,
}
},
{
where: {
id: req.decoded.id
}
},
).then(response => {
res.status(200).json({ status: 200, data: { response } });
})
.catch(error => {
res.status(500).json({ status: 500, err: error });
})
})

我试过:

let new_avatar = (Paperclip.plugins, {
avatar: {
styles: [
{ original: true },
{ large: { width: 500, height: 500 } },
{ medium: { width: 200, height: 200 } },
{ thumb: { width: 100, height: 100 } }
],
prefix: `/users/avatars/{{attachment}}/{{id}}/{{filename}}`,
name_format: '{{style}}.{{extension}}',
storage: 's3',
s3: {
bucket: process.env.S3_BUCKET_NAME,
region: 'us-west-2',
key: process.env.AWS_ACCESS_KEY_ID,
secret: process.env.AWS_SECRET_ACCESS_KEY,
}
},
})

let data = {
avatar: new_avatar
}

models.Users.update(
data,
{
where: {
id: req.decoded.id
}
},
).then(response => {
res.status(200).json({ status: 200, data: { response } });
})
.catch(error => {
res.status(500).json({ status: 500, err: error });
})

从上面链接中的示例中,我不明白它是如何保存到 S3 的,或者它是如何以 Rails gem 创建该记录的相同方式更新数据库的。

问题:如何以与 Rails 回形针 gem 保存到 S3 和数据库中的 user 记录完全相同的方式保存调整大小的图像 + 原始图像。

我最初是为了 400 点赏金而开放的,我很高兴仍然向任何可以帮助我解决这个问题的人提供 400 点赏金。谢谢!!

最佳答案

以下代码适用于 nodeJs。 我添加了一个 API 来将图像从前端保存到 AWS S3。

为了更好地理解,我在代码中添加了注释。

var express = require("express");
var router = express.Router();
var aws = require('aws-sdk');
aws.config.update({
secretAccessKey: config.AwsS3SecretAccessKey,
accessKeyId: config.AwsS3AccessKeyId,
region: config.AwsS3Region
});

router
.route("/uploadImage")
.post(function (req, res) {

//req.files.imageFile contains the file from client, modify it as per you requirement
var file = getDesiredFileFromPaperclip(req.files.imageFile);
const fileName = new Date().getTime() + file.name;

//before uploading, we need to create an instance of client file
file.mv(fileName, (movErr, movedFile) => {
if (movErr) {
console.log(movErr);
res.send(400);
return;
}
//read file data
fs.readFile(fileName, (err, data) => {
if (err) {
console.error(err)
res.send(400);
}
else {

//as we have byte data of file, delete the file instance
try {
fs.unlink(fileName);
} catch (error) {
console.error(error);
}

//now, configure aws

var s3 = new aws.S3();
const params = {
Bucket: config.AwsS3BucketName, // pass your bucket name
Key: fileName, // file will be saved as bucket_name/file.ext
Body: data
}

//upload file
s3.upload(params, function (s3Err, awsFileData) {
if (s3Err) {
console.error(s3Err)
res.send(400);
} else {
console.log(`File uploaded successfully at ${awsFileData.Location}`)

//update uploaded file data in database using 'models.Users.update'

//send response to client/frontend
var obj = {};
obj.status = { "code": "200", "message": "Yipee!! Its Done" };
obj.result = { url: awsFileData.Location };
res.status(200).send(obj);
}
});
}
});
});
});

这是老派的、不花哨的解决方案。请尝试一下并告诉我。

关于node.js - 上传图片 - Nodejs Paperclip 和 S3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57047538/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com