首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法读取上传到亚马逊网络服务S3的图像

无法读取上传到亚马逊网络服务S3的图像
EN

Stack Overflow用户
提问于 2021-02-09 23:02:40
回答 2查看 191关注 0票数 1

我将图片上传到AWS S3作为缓冲区(正如aws-sdk所要求的),但是这个图片不能作为普通图片读取--它在浏览器中看起来就像一个小的白色方块。我错过了什么?

关于Next.js应用编程接口

代码语言:javascript
复制
const s3 = new AWS.S3({
      accessKeyId: "key",
      secretAccessKey: "key",
    });
    const params = {
      Bucket: "bucket",
      Key: `${Date.now().toString()}.jpg`,
      Body: Buffer.from(req.body),
      ContentType: "image/png",
    };
    s3.upload(params, (err, data) => {
      if (err) {
        throw err;
      }
      console.log(`File uploaded successfully. ${data}`);
    });

客户端:

代码语言:javascript
复制
const handleImageUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { files } = e.target;
    const formData = new FormData();
    if (files && files[0]) {
      formData.append("image", files[0]);
      fetch("/api/upload.image", {
        method: "POST",
        body: formData,
      });
    }
  };

以下是来自服务器的答案的示例:

代码语言:javascript
复制
<ref *2> ManagedUpload {
  _events: {},
  body: <Buffer 2d 2d 2d 2d 2d 2d 57 65 62 4b 69 74 46 6f 72 6d 42 6f 75 6e 64 61 72 79 51 41 62 63 59 76 32 45 4e 6c 34 77 77 79 70 57 0d 0a 43 6f 6e 74 65 6e 74 2d ... 93798 more bytes>,
  sliceFn: [Function: slice],
  callback: [Function (anonymous)],
  parts: {},
  completeInfo: [],
  fillQueue: [Function: fillBuffer],
  partSize: 5242880,
  service: Service {
    config: Config {
      credentials: [Credentials],
      credentialProvider: [CredentialProviderChain],
      region: 'us-east-1',
      logger: null,
      apiVersions: {},
      apiVersion: null,
      endpoint: 's3.amazonaws.com',
      httpOptions: [Object],
      maxRetries: undefined,
      maxRedirects: 10,
      paramValidation: true,
      sslEnabled: true,
      s3ForcePathStyle: false,
      s3BucketEndpoint: false,
      s3DisableBodySigning: true,
      s3UsEast1RegionalEndpoint: undefined,
      s3UseArnRegion: undefined,
      computeChecksums: true,
      convertResponseTypes: true,
      correctClockSkew: false,
      customUserAgent: null,
      dynamoDbCrc32: true,
      systemClockOffset: 0,
      signatureVersion: 'v4',
      signatureCache: true,
      retryDelayOptions: {},
      useAccelerateEndpoint: false,
      clientSideMonitoring: false,
      endpointDiscoveryEnabled: undefined,
      endpointCacheSize: 1000,
      hostPrefixEnabled: true,
      stsRegionalEndpoints: 'legacy',
      accessKeyId: 'xxx',
      secretAccessKey: 'xxx',
      params: [Object]
    },
    isGlobalEndpoint: false,
    endpoint: Endpoint {
      protocol: 'https:',
      host: 's3.amazonaws.com',
      port: 443,
      hostname: 's3.amazonaws.com',
      pathname: '/',
      path: '/',
      href: 'https://s3.amazonaws.com/'
    },
    _events: { apiCallAttempt: [Array], apiCall: [Array] },
    MONITOR_EVENTS_BUBBLE: [Function: EVENTS_BUBBLE],
    CALL_EVENTS_BUBBLE: [Function: CALL_EVENTS_BUBBLE],
    _clientId: 2
  },
  totalBytes: 93848,
  failed: false,
  partPos: 5242880,
  isDoneChunking: true,
  numParts: 1,
  totalPartNumbers: 1,
  singlePart: <ref *1> Request {
    domain: null,
    service: Service {
      config: [Config],
      isGlobalEndpoint: false,
      endpoint: [Endpoint],
      _events: [Object],
      MONITOR_EVENTS_BUBBLE: [Function: EVENTS_BUBBLE],
      CALL_EVENTS_BUBBLE: [Function: CALL_EVENTS_BUBBLE],
      _clientId: 2
    },
    operation: 'putObject',
    params: {
      Body: <Buffer 2d 2d 2d 2d 2d 2d 57 65 62 4b 69 74 46 6f 72 6d 42 6f 75 6e 64 61 72 79 51 41 62 63 59 76 32 45 4e 6c 34 77 77 79 70 57 0d 0a 43 6f 6e 74 65 6e 74 2d ... 93798 more bytes>,
      Bucket: 'codest-images',
      Key: '1613572736403.jpg',
      ContentType: 'image/png',
      ACL: 'public-read'
    },
    httpRequest: HttpRequest {
      method: 'PUT',
      path: '/1613572736403.jpg',
      headers: [Object],
      body: <Buffer 2d 2d 2d 2d 2d 2d 57 65 62 4b 69 74 46 6f 72 6d 42 6f 75 6e 64 61 72 79 51 41 62 63 59 76 32 45 4e 6c 34 77 77 79 70 57 0d 0a 43 6f 6e 74 65 6e 74 2d ... 93798 more bytes>,
      endpoint: [Object],
      region: 'us-east-1',
      _userAgent: 'aws-sdk-nodejs/2.840.0 darwin/v14.15.4 callback',
      virtualHostedBucket: 'codest-images',
      stream: [ClientRequest]
    },
    startTime: 2021-02-17T14:38:56.406Z,
    response: Response {
      request: [Circular *1],
      data: null,
      error: null,
      retryCount: 0,
      redirectCount: 0,
      httpResponse: [HttpResponse],
      maxRetries: 3,
      maxRedirects: 10
    },
    _asm: AcceptorStateMachine { currentState: 'send', states: [Object] },
    _haltHandlersOnError: false,
    _events: {
      validate: [Array],
      afterBuild: [Array],
      restart: [Array],
      sign: [Array],
      validateResponse: [Array],
      send: [Array],
      httpHeaders: [Array],
      httpData: [Array],
      httpDone: [Array],
      retry: [Array],
      afterRetry: [Array],
      build: [Array],
      extractData: [Array],
      extractError: [Array],
      httpError: [Array],
      beforePresign: [Array],
      success: [Array],
      complete: [Array],
      httpUploadProgress: [Array]
    },
    emit: [Function: emit],
    API_CALL_ATTEMPT: [Function: API_CALL_ATTEMPT],
    API_CALL_ATTEMPT_RETRY: [Function: API_CALL_ATTEMPT_RETRY],
    API_CALL: [Function: API_CALL],
    _managedUpload: [Circular *2],
    signedAt: 2021-02-17T14:38:56.415Z
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-18 21:56:47

最后,它是这样解决的。

代码语言:javascript
复制
import { NextApiRequest, NextApiResponse } from "next";
import AWS from "aws-sdk";
import fs from "fs";
import formidable, { File as FFile } from "formidable";

export const config = {
  api: {
    bodyParser: false,
  },
};

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
): Promise<void> {
  try {
    const s3 = new AWS.S3({
      accessKeyId: "xxx",
      secretAccessKey: "xxx",
    });

    const form = new formidable.IncomingForm();
    form.uploadDir = "./";
    form.keepExtensions = true;
    form.parse(req, (err, fields, files) => {
      fs.readFile((files.image as FFile).path, (_, image) => {
        const params = {
          Bucket: "codest-images",
          Key: (files.image as FFile).name,
          Body: image,
          ContentType: (files.image as FFile).type,
          ContentSize: (files.image as FFile).size,
          ACL: "public-read",
        };
        s3.upload(
          params,
          (error: Error, data: AWS.S3.ManagedUpload.SendData) => {
            if (error) {
              res.status(400).json(error.message);
              res.end();
            } else {
              res.status(200).json(data.Location);
            }
          }
        );
      });
    });
  } catch (ex) {
    res.status(400).json({ err: ex });
    res.end();
  }
}
票数 0
EN

Stack Overflow用户

发布于 2021-02-18 14:08:00

您正在尝试从req.body获取图像内容,但这是错误的。如果你在控制台上打印req.body,你会看到类似这样的东西-

代码语言:javascript
复制
------WebKitFormBoundary
Content-Disposition: form-data; name="image"; 
filename="image.jpeg"
Content-Type: application/json
your file content buffer

您可以对其进行解析,以获得缓冲区内容。或者我更喜欢使用像multer这样的库来读取FormData中的文件。以下是使用multer的NextJS代码。

代码语言:javascript
复制
const AWS = require("aws-sdk");
const s3 = new AWS.S3();
var multer = require("multer");
var upload = multer();

export const config = {
  api: {
    bodyParser: false, // This is important. Else multer won't be parsing your form data
  },
};

export default async function handler(req, res) {
  upload.single("image")(req, {}, (err) => { // 'image' is the element name in the form
    console.log(req.file); // you will see file metadata and the buffer here
    const params = {
      Bucket: "bucket",
      Key: `${Date.now().toString()}.jpg`,
      Body: req.file.buffer,
      ContentType: "image/jpeg",
    };
    s3.upload(params, (err, data) => {
      if (err) {
        res.status(500).send({ message: "Error while uploading" });
      } else {
        console.log(`File uploaded successfully`, data);
        res.status(200).send({ message: "File uploaded succesfully" });
      }
    });
  });
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66121533

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档