How can I upload images to an Amazon S3 bucket using Next.js 13's app router and overcome API route structure changes?

huangapple go评论52阅读模式
英文:

How can I upload images to an Amazon S3 bucket using Next.js 13's app router and overcome API route structure changes?

问题

如何在Next.js 13上使用应用程序路由器将图像上传到Amazon S3存储桶?

我尝试使用formidable和multer,但由于Next.js更改了其API路由结构,这两种解决方案都无法正常工作:

import { NextRequest, NextResponse } from "next/server";
import { v4 as uuid } from "uuid";
import multer from "multer";
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { IncomingForm } from "formidable";

const s3Client = new S3Client({
  region: process.env.REGION as string,
  credentials: {
    accessKeyId: process.env.ACCESS_KEY as string,
    secretAccessKey: process.env.SECRET_KEY as string,
  },
});

async function uploadImageToS3(
  file: Buffer,
  fileName: string
): Promise<string> {
  const params = {
    Bucket: process.env.BUCKET_NAME as string,
    Key: `${Date.now()}-${fileName}`,
    Body: file,
    ContentType: "image/jpeg", // 根据需要更改内容类型
  };

  const command = new PutObjectCommand(params);
  await s3Client.send(command);

  return fileName;
}

export async function POST(request: NextRequest, response: NextResponse) {
  try {
    const formData = await request.formData();

    // 如何传递缓冲区并将图像存储在S3存储桶中??

  } catch (error) {
    console.error("上传图像时出错:", error);
    NextResponse.json({ message: "上传图像出错" });
  }
}
英文:

How to upload images to amazon s3 bucket on nextjs13 using app router?

I tried using formidable and multer but both soltions are not working as nextjs changes their api routes structure:

import { NextRequest, NextResponse } from &quot;next/server&quot;;
import { v4 as uuid } from &quot;uuid&quot;;
import multer from &quot;multer&quot;;
import { S3Client, PutObjectCommand } from &quot;@aws-sdk/client-s3&quot;;
import { IncomingForm } from &quot;formidable&quot;;

const s3Client = new S3Client({
  region: process.env.REGION as string,
  credentials: {
    accessKeyId: process.env.ACCESS_KEY as string,
    secretAccessKey: process.env.SECRET_KEY as string,
  },
});

async function uploadImageToS3(
  file: Buffer,
  fileName: string
): Promise&lt;string&gt; {
  const params = {
    Bucket: process.env.BUCKET_NAME as string,
    Key: `${Date.now()}-${fileName}`,
    Body: file,
    ContentType: &quot;image/jpeg&quot;, // Change the content type accordingly
  };

  const command = new PutObjectCommand(params);
  await s3Client.send(command);

  return fileName;
}

export async function POST(request: NextRequest, response: NextResponse) {
  try {
    const formData = await request.formData();

    // How to pass the buffer and store the image on s3 bucket ???

  } catch (error) {
    console.error(&quot;Error uploading image:&quot;, error);
    NextResponse.json({ message: &quot;Error uploading image&quot; });
  }
}

答案1

得分: 5

最终,在尝试了很多次后,这是解决方案:

import { NextRequest, NextResponse } from "next/server";
import { v4 as uuid } from "uuid";
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import sharp from "sharp";

const s3Client = new S3Client({
  region: process.env.REGION as string,
  credentials: {
    accessKeyId: process.env.ACCESS_KEY as string,
    secretAccessKey: process.env.SECRET_KEY as string,
  },
});

async function uploadImageToS3(
  file: Buffer,
  fileName: string
): Promise<string> {
  const resizedImageBuffer = await sharp(file)
    .resize(400, 500) // Specify your desired width or height for resizing
    .toBuffer();

  const params = {
    Bucket: process.env.BUCKET_NAME as string,
    Key: `${Date.now()}-${fileName}`,
    Body: resizedImageBuffer,
    ContentType: "image/jpeg", // Change the content type accordingly
  };

  const command = new PutObjectCommand(params);
  await s3Client.send(command);

  return fileName;
}

export async function POST(request: NextRequest, response: NextResponse) {
  try {
    const formData = await request.formData();
    const file = formData.get("file") as Blob | null;
    if (!file) {
      return NextResponse.json(
        { error: "File blob is required." },
        { status: 400 }
      );
    }

    const mimeType = file.type;
    const fileExtension = mimeType.split("/")[1];

    const buffer = Buffer.from(await file.arrayBuffer());
    const fileName = await uploadImageToS3(
      buffer,
      uuid() + "." + fileExtension
    );

    return NextResponse.json({ success: true, fileName });
  } catch (error) {
    console.error("Error uploading image:", error);
    NextResponse.json({ message: "Error uploading image" });
  }
}
英文:

Finally after much trying, here is the solution:

import { NextRequest, NextResponse } from &quot;next/server&quot;;
import { v4 as uuid } from &quot;uuid&quot;;
import { S3Client, PutObjectCommand } from &quot;@aws-sdk/client-s3&quot;;
import sharp from &quot;sharp&quot;;

const s3Client = new S3Client({
  region: process.env.REGION as string,
  credentials: {
    accessKeyId: process.env.ACCESS_KEY as string,
    secretAccessKey: process.env.SECRET_KEY as string,
  },
});

async function uploadImageToS3(
  file: Buffer,
  fileName: string
): Promise&lt;string&gt; {
  const resizedImageBuffer = await sharp(file)
    .resize(400, 500) // Specify your desired width or height for resizing
    .toBuffer();

  const params = {
    Bucket: process.env.BUCKET_NAME as string,
    Key: `${Date.now()}-${fileName}`,
    Body: resizedImageBuffer,
    ContentType: &quot;image/jpeg&quot;, // Change the content type accordingly
  };

  const command = new PutObjectCommand(params);
  await s3Client.send(command);

  return fileName;
}

export async function POST(request: NextRequest, response: NextResponse) {
  try {
    const formData = await request.formData();
    const file = formData.get(&quot;file&quot;) as Blob | null;
    if (!file) {
      return NextResponse.json(
        { error: &quot;File blob is required.&quot; },
        { status: 400 }
      );
    }

    const mimeType = file.type;
    const fileExtension = mimeType.split(&quot;/&quot;)[1];

    const buffer = Buffer.from(await file.arrayBuffer());
    const fileName = await uploadImageToS3(
      buffer,
      uuid() + &quot;.&quot; + fileExtension
    );

    return NextResponse.json({ success: true, fileName });
  } catch (error) {
    console.error(&quot;Error uploading image:&quot;, error);
    NextResponse.json({ message: &quot;Error uploading image&quot; });
  }
}

答案2

得分: 0

你需要修改代码。希望这对你有帮助。

import { NextRequest, NextResponse } from "next/server";
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { createReadStream } from "fs";
import { v4 as uuid } from "uuid";

const s3Client = new S3Client({
  region: process.env.REGION as string,
  credentials: {
    accessKeyId: process.env.ACCESS_KEY as string,
    secretAccessKey: process.env.SECRET_KEY as string,
  },
});

async function uploadImageToS3(
  fileStream: NodeJS.ReadableStream,
  fileName: string
): Promise<string> {
  const params = {
    Bucket: process.env.BUCKET_NAME as string,
    Key: `${Date.now()}-${fileName}`,
    Body: fileStream,
    ContentType: "image/jpeg",
  };

  const command = new PutObjectCommand(params);
  await s3Client.send(command);

  return fileName;
}

export async function POST(request: NextRequest, response: NextResponse) {
  try {
    const { file } = request.files; // 假设文件输入的名称为 'file'
    const { path, name } = file;

    const fileStream = createReadStream(path);
    const uploadedFileName = await uploadImageToS3(fileStream, name);

    response.json({ fileName: uploadedFileName });
  } catch (error) {
    console.error("上传图片出错:", error);
    response.json({ message: "上传图片出错" });
  }
}
英文:

You need to modify code. Hope this helpful for you.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

import { NextRequest, NextResponse } from &quot;next/server&quot;;
import { S3Client, PutObjectCommand } from &quot;@aws-sdk/client-s3&quot;;
import { createReadStream } from &quot;fs&quot;;
import { v4 as uuid } from &quot;uuid&quot;;
const s3Client = new S3Client({
region: process.env.REGION as string,
credentials: {
accessKeyId: process.env.ACCESS_KEY as string,
secretAccessKey: process.env.SECRET_KEY as string,
},
});
async function uploadImageToS3(
fileStream: NodeJS.ReadableStream,
fileName: string
): Promise&lt;string&gt; {
const params = {
Bucket: process.env.BUCKET_NAME as string,
Key: `${Date.now()}-${fileName}`,
Body: fileStream,
ContentType: &quot;image/jpeg&quot;,
};
const command = new PutObjectCommand(params);
await s3Client.send(command);
return fileName;
}
export async function POST(request: NextRequest, response: NextResponse) {
try {
const { file } = request.files; // Assuming the file input name is &#39;file&#39;
const { path, name } = file;
const fileStream = createReadStream(path);
const uploadedFileName = await uploadImageToS3(fileStream, name);
response.json({ fileName: uploadedFileName });
} catch (error) {
console.error(&quot;Error uploading image:&quot;, error);
response.json({ message: &quot;Error uploading image&quot; });
}
}

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年6月1日 14:56:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76379368.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定