【问题标题】:How to upload file to Digital Ocean Spaces using Javascript如何使用 Javascript 将文件上传到 Digital Ocean Spaces
【发布时间】:2018-03-19 22:53:36
【问题描述】:

我希望使用 Digital Oceans 空间(似乎与 S3 具有相同的 API),并希望通过上传示例文件来尝试。我有很多困难。这是我到目前为止所做的事情

{'hi' : 'world'}

是我要上传的文件hiworld.json 的内容。我了解我需要先创建一个 aws v4 签名才能提出此请求。

var aws4 = require('aws4') var request = require('request')

var opts = {'json': true,'body': "{'hi':'world'}",host: '${myspace}.nyc3.digitaloceanspaces.com', path: '/hiworld.json'}

aws4.sign(opts, {accessKeyId: '${SECRET}', secretAccessKey: '${SECRET}'})

然后我发送请求

request.put(opts,function(error, response) {
    if(error) {
        console.log(error);
    }
    console.log(response.body);
});

但是,当我检查我的 Digital Ocean 空间时,我发现我的文件没有创建。我注意到,如果我将 PUT 更改为 GET 并尝试访问现有文件,我没有问题。

这是我的标题的样子

headers: { Host: '${myspace}.nyc3.digitaloceanspaces.com', 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 'Content-Length': 14, 'X-Amz-Date': '20171008T175325Z', Authorization: 'AWS4-HMAC-SHA256 Credential=${mykey}/20171008/us-east-1//aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date, Signature=475e691d4ddb81cca28eb0dcdc7c926359797d5e383e7bef70989656822accc0' }, method: 'POST' }

【问题讨论】:

    标签: javascript amazon-s3 digital-ocean


    【解决方案1】:

    作为替代方案,使用aws-sdk:

    // 1. Importing the SDK
    import AWS from 'aws-sdk';
    
    // 2. Configuring the S3 instance for Digital Ocean Spaces 
    const spacesEndpoint = new AWS.Endpoint(
      `${REGION}.digitaloceanspaces.com`
    );
    const url = `https://${BUCKET}.${REGION}.digitaloceanspaces.com/${file.path}`;
    const S3 = new AWS.S3({
      endpoint: spacesEndpoint,
      accessKeyId: ACCESS_KEY_ID,
      secretAccessKey: SECRET_ACCESS_KEY
    });
    
    // 3. Using .putObject() to make the PUT request, S3 signs the request
    const params = { Body: file.stream, Bucket: BUCKET, Key: file.path };
    S3.putObject(params)
      .on('build', request => {
        request.httpRequest.headers.Host = `https://${BUCKET}.${REGION}.digitaloceanspaces.com`;
        // Note: I am assigning the size to the file Stream manually
        request.httpRequest.headers['Content-Length'] = file.size;
        request.httpRequest.headers['Content-Type'] = file.mimetype;
        request.httpRequest.headers['x-amz-acl'] = 'public-read';
      })
      .send((err, data) => {
        if (err) logger(err, err.stack);
        else logger(JSON.stringify(data, '', 2));
      });
    

    【讨论】:

      【解决方案2】:
      var str = {
          'hi': 'world'
      }
      
      var c = JSON.stringify(str);
      
      request(aws4.sign({
        'uri': 'https://${space}.nyc3.digitaloceanspaces.com/newworlds.json',
        'method': 'PUT',
        'path': '/newworlds.json',
        'headers': {
          "Cache-Control":"no-cache",
          "Content-Type":"application/x-www-form-urlencoded",
          "accept":"*/*",
          "host":"${space}.nyc3.digitaloceanspaces.com",
          "accept-encoding":"gzip, deflate",
          "content-length": c.length
        },
        body: c
      },{accessKeyId: '${secret}', secretAccessKey: '${secret}'}),function(err,res){
          if(err) {
              console.log(err);
          } else {
              console.log(res);
          }
      })
      

      这给了我一个成功的 PUT

      【讨论】:

        【解决方案3】:

        可以使用 multer 和 aws sdk 来完成。它对我有用。

        const aws = require('aws-sdk');
        const multer = require('multer');
        const express = require('express');
        const multerS3 = require('multer-s3');
        const app = express();
        
        const spacesEndpoint = new aws.Endpoint('sgp1.digitaloceanspaces.com');
        const spaces = new aws.S3({
        endpoint: spacesEndpoint,
        accessKeyId: 'your_access_key_from_API',
        secretAccessKey: 'your_secret_key'
         });
        
        
        const upload = multer({
        storage: multerS3({
        s3: spaces,
        bucket: 'bucket-name',
        acl: 'public-read',
        key: function (request, file, cb) {
          console.log(file);
          cb(null, file.originalname);
           }
         })
         }).array('upload', 1);
        

        现在您也可以使用这样的 API 调用它

        app.post('/upload', function (request, response, next) {
        upload(request, response, function (error) {
        if (error) {
          console.log(error);
        
        }
        console.log('File uploaded successfully.');
        
           });
          });
        

        HTML 看起来像这样

        <form method="post" enctype="multipart/form-data" action="/upload">
        <label for="file">Upload a file</label>
        <input type="file" name="upload">
        <input type="submit" class="button">
        </form>
        

        【讨论】:

        • 记住分配acl: 'public-read' 没有区别。上传的文件仍然是私密的
        猜你喜欢
        • 2023-01-31
        • 2019-05-11
        • 1970-01-01
        • 2018-05-21
        • 1970-01-01
        • 1970-01-01
        • 2022-12-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多