Next.js中怎么上传图片到阿里云OSS

在 Next.js中上传图片到阿里云 OSS 可以按照以下步骤进行:

一、安装依赖
首先安装阿里云 OSS 的 SDK:

npm i ali-oss
npm i -D @types/ali-oss

二、配置阿里云OSS
在src目录下中创建一个用于配置 OSS 的文件,比如ossConfig.ts

import OSS from 'ali-oss';

const ossClient = new OSS({
  region: 'your-region',
  accessKeyId: 'your-access-key-id',
  accessKeySecret: 'your-access-key-secret',
  bucket: 'your-bucket-name',
  endpoint: 'your-endpoint',
});

export default ossClient;

将your-region、your-access-key-id、your-access-key-secret、your-bucket-name和your-endpoint替换为你的实际阿里云 OSS 配置信息。

三、上传图片
下面例子使用了hono.js来作为api路由

1.创建一个处理上传的 API 路由,比如在app/api/[[...route]]/upload.js文件中:

import { Hono } from "hono";
import { format } from "date-fns";
import { v4 as uuid } from "uuid";
import ossClient from '@/ossConfig';


const app = new Hono();

app.post('/uploadToOSS', async (c) => {
    const body = await c.req.parseBody();
    // console.log(body);
    const file = body['image'] as File;
    //   console.log(file);
    //限制只能上传图片类型
    const fileType = file.type;
    if (!fileType.startsWith('image/')) {
        return c.json({ status: 1, msg: '只能上传图片' });
    }
    const fileName = `images/${format(new Date(), 'yyyy-MM-dd')}/${uuid()}_${file.name}`;
    //   console.log(fileName);

    try {
        // 将文件转换为 Buffer
        const buffer = await file.arrayBuffer();
        const result = await ossClient.put(fileName, Buffer.from(buffer));
        // console.log(result);
        if (result.res.status === 200) {
            return c.json({ status: 0, msg: '图片上传成功', url: result.url });
        } else {
            return c.json({ status: 1, msg: '图片上传失败' });
        }
    } catch (error) {
        return c.json({ status: 1, msg: '图片上传失败', error: error });
    }

});

export default app;

2.创建一个前端上传页面:

"use client";

import { ChangeEvent, FormEvent,useState } from 'react';

const uploadPage = () => {
    const [selectedFile, setSelectedFile] = useState<File | null>(null);
    const handleFileChange = (e:ChangeEvent<HTMLInputElement>) => {
        if(e.target.files){
            setSelectedFile(e.target.files[0]);
        }
      };
     
      const handleSubmit = async (e:FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        const formData = new FormData();
        formData.append('image', selectedFile!);
        const response = await fetch('/api/upload/uploadToOSS', {
          method: 'POST',
          body: formData,
        });
        const data = await response.json();
        // 处理上传成功后的返回结果
        console.log(data);
        if(data.status === 0){
            alert("上传成功");
            //返回的图片地址是data.url
        }else{
            alert("上传失败");
        }
       
      };

    return (
        <div>
            <form onSubmit={handleSubmit}>
                <input type="file" onChange={handleFileChange} />
                <button type="submit">上传</button>
            </form>
        </div>
    );
};

export default uploadPage;

这样就可以在 Next.js 14 中实现将图片上传到阿里云 OSS。

四、实现点击按钮直接上传
如果不想先选择文件,然后再点击上传按钮上传。想直接点击按钮,用户选择完文件就自动上传,可以按照下面方法来操作:
将用户选择文件事件和上传事件放到一个方法里面
代码如下:

import { ChangeEvent } from "react";


const uploadPage = () => {

    const handleFileChange = async (e: ChangeEvent<HTMLInputElement>) => {
        if (!e.target.files) return;
        const file = e.target.files[0];
        if (!file) return;
        // console.log(file);
        const formData = new FormData();
        formData.append('image', file!);
        const response = await fetch('/api/upload/uploadToOSS', {
            method: 'POST',
            body: formData,
        });
        const data = await response.json();
        // 处理上传成功后的返回结果
        // console.log(data);
        if (data.status === 0) {
            alert("上传成功");
            //返回的图片地址是data.url
        } else {
            alert("上传失败");
        }
    };


    return (
        <div>
            <label
                htmlFor="upload"
                className="flex justify-center items-center w-full
                text-white text-sm font-medium
                 bg-blue-600 hover:bg-blue-600 py-2
                 rounded-md cursor-pointer"
>
                上传图片
                <input id="upload" type="file" onChange={handleFileChange} className="hidden" />
            </label>
        </div>
    )
}

export default uploadPage;

发表评论

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