AngularJs图像上传到S3

2023-12-15

I am:
- 创建网络应用程序
- 带有 ng 文件上传功能的 AngularJS 前端(https://github.com/danialfarid/ng-file-upload)
- Node.js 后端
- 希望能够将图像上传到我的 Amazon S3 存储桶

我正在尝试遵循本教程:https://github.com/danialfarid/ng-file-upload/wiki/Direct-S3-upload-and-Node-signing-example

本质上,程序流程是选择文件,单击按钮,请求后端签名,然后上传到 S3。

我收到来自后端的签名,代码为 200,但是当前端尝试上传图像时,我在开发人员菜单中看到:
OPTIONS https://mybucket.name.s3-us-east-1.amazonaws.com/ net::ERR_NAME_NOT_RESOLVED

是我的代码有问题还是我设置存储桶的方式有问题?

如果需要添加代码:

我的 S3 存储桶上的 CORS

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>my.computers.IP.Address</AllowedOrigin>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

Node.js 后端代码

app.post('/signing', function(req, res) {
    var request = req.body;
    var fileName = request.filename

    var extension = fileName.substring(fileName.lastIndexOf('.'));
    var today = new Date();
    var path = '/' + today.getFullYear() + '/' + today.getMonth() + '/' + today.getDate() + '/' + uuid.v4() + extension;

    var readType = 'private';

    var expiration = moment().add(5, 'm').toDate(); //15 minutes

    var s3Policy = {
        'expiration': expiration,
        'conditions': [{
                'bucket': aws.bucket
            },
            ['starts-with', '$key', path], 
            {
                'acl': readType
            },
            {
              'success_action_status': '201'
            },
            ['starts-with', '$Content-Type', request.type],
            ['content-length-range', 2048, 10485760], //min and max
        ]
    };

    var stringPolicy = JSON.stringify(s3Policy);
    var base64Policy = new Buffer(stringPolicy, 'utf-8').toString('base64');

    // sign policy
    var signature = crypto.createHmac('sha1', aws.secret)
        .update(new Buffer(base64Policy, 'utf-8')).digest('base64');

    var credentials = {
        url: s3Url,
        fields: {
            key: path,
            AWSAccessKeyId: aws.key,
            acl: readType,
            policy: base64Policy,
            signature: signature,
            'Content-Type': request.type,
            success_action_status: 201
        }
    };
    res.jsonp(credentials);
});

AngularJS 前端代码

App.controller('MyCtrl2', ['$scope', '$http', 'Upload', '$timeout', function ($scope, $http, Upload, $timeout) {
    $scope.uploadPic = function(file) {
        var filename = file.name;
        var type = file.type;
        var query = {
            filename: filename,
            type: type
        };
        $http.post('/signing', query)
            .success(function(result) {
                Upload.upload({
                    url: result.url, //s3Url
                    transformRequest: function(data, headersGetter) {
                        var headers = headersGetter();
                        delete headers.Authorization;
                        return data;
                    },
                    fields: result.fields, //credentials
                    method: 'POST',
                    file: file
                }).progress(function(evt) {
                    console.log('progress: ' + parseInt(100.0 * evt.loaded / evt.total));
                }).success(function(data, status, headers, config) {
                    // file is uploaded successfully
                    console.log('file ' + config.file.name + 'is uploaded successfully. Response: ' + data);
                }).error(function() {

                });
            })
            .error(function(data, status, headers, config) {
                // called asynchronously if an error occurs
                // or server returns response with an error status.
        });
    };
}]);

该示例包含一些我认为过于简单化的错误。

var s3Url = 'https://' + aws.bucket + '.s3-' + aws.region + '.amazonaws.com';

这在很多时候都有效,但它不是一个始终如一地在 S3 中创建对象 URL 的有效方法。

它至少在两种情况下会崩溃,其中之一就是您遇到的情况。

的端点为美国标准S3 区域,位于美国东部1AWS 的区域,不是s3-us-east-1.amazonaws.com,就像它对所有其他区域使用相同的格式一样。由于似乎是遗留/进化的原因,这只是s3.amazonaws.com但也可以写成s3-external-1.amazonaws.com。 (请记住,截至撰写本文时,S3 已经存在了近十年,并且该服务已经扩展和发展,同时保持向后兼容性——这是一项值得注意的壮举,但必然会导致一些乍一看令人困惑的约定。)

然而,所有的存储桶——包括那些不在 us-east-1 中的存储桶——但不包括那些因第二个原因(我还没有讲到)而破坏上述代码的存储桶——可以简单地解决为bucket-name.s3.amazonaws.com-- 如果您考虑 DNS 的分层性质,您可以看到它是如何工作的:创建存储桶后几分钟内,S3 会在 DNS 中重新映射该特定主机名,以将请求发送到正确的区域 S3 端点。

So the + '.s3-' + aws.region +如果写的话应该可以工作,简单地说,+ '.s3' +.

...当然,除非您创建了一个名称中带有点的存储桶。在这种情况下,您将遇到 https 问题(这是上面提到的问题#2),因为名称中带有点的存储桶将与 S3 提供的通配符 SSL (TLS) 证书不匹配(SSL 中的设计限制)通配符证书,而不是 S3 本身)。

如果这是一个问题,并且出于某种原因不希望使用名称中不带点的存储桶,则您的 URL 必须以所谓的方式制作路径式格式。这是替代方案虚拟风格格式,其中存储桶名称位于主机名中。这里,存储桶名称是路径的第一部分:

https://s3[-region].amazonaws.com/bucket.name.with.dots/key-path

...并且,再说一遍,第一个组件只是s3 or s3-external-1对于美国标准 (us-east-1)...但使用此格式需要您匹配区域,与上面的不同,其中 DNS 处理请求路由...否则 S3 将抛出永久重定向错误。

http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html

http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region

这是很多信息,但希望不仅有助于解释您需要采取哪些不同的做法,还有助于解释原因。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

AngularJs图像上传到S3 的相关文章

随机推荐

  • minikube 和 ingress-nginx 没有打开端口 80

    我是 ingress nginx 的新手 我使用 minikube 启用了它minikube addons enable ingress 在寻找与 ingress nginx 相关的服务时 我跑了kubectl get services n
  • 如何在 WPF 中添加自定义路由命令?

    我有一个包含菜单和子菜单的应用程序 我已将应用程序命令附加到一些子菜单项 例如剪切 复制和粘贴 我还有一些其他没有应用程序命令的菜单项 如何将自定义命令绑定添加到这些子菜单项 我已经经历过this文章但无法将事件附加到我的子菜单项 我使用放
  • WebUSB - “无法声明接口”错误

    我尝试使用下面的代码通过 WebUSB API 使用 POS 打印机 但失败了 claimInterface 错误为DOMException Unable to claim interface 所有测试均在 Linux 上的 Chrome
  • 如何使用 Tesseract 提高图像质量以从图像中提取文本

    我试图在下面的代码中使用 Tesseract 来提取图像的两行 我尝试提高图像质量 但没有成功 谁能帮我 from PIL import Image ImageEnhance ImageFilter import pytesseract i
  • VB6 中的运行时错误堆栈跟踪或位置

    我维护一个用 VB6 编写的旧应用程序 在客户端环境中 它会引发运行时错误 我无法在调试器下重现该错误 有什么方法可以获取堆栈跟踪或错误位置吗 我的意思是 不要在代码中放置跟踪语句 例如here或添加错误处理程序以记录每个过程 例如here
  • 如何在 Mac 上将 adb 与 genymotion 结合使用?

    我正在 Mac OS X 10 9 4 上使用 cordova 构建 Android 应用程序 我正在使用 genymotion 创建虚拟设备 昨天 我能够获得 cordova run android 让我的应用程序在 genymotion
  • 反射不适用于 Android 发布的 apk。即使禁用了 proguard/minify

    目前我面临一个奇怪的问题 我的应用程序的发布 apk 抛出 NoSuchFieldExceptions 它在调试 apk 上运行良好 我试图获取的字段是 android widget 打包的 我还努力启用 proguard 并在 progu
  • 如何更改自定义子面板中的默认排序 - Sugarcrm?

    我想在自定义面板中按 创建日期 进行默认排序 您能指导我吗 如何将其设为 创建日期 作为默认排序 请帮我 In your layout defs改变sort by到所需的列 在此示例中 用于排序的默认列是date entered
  • jinja2 如何删除日期时间中的微秒

    在 Jinja2 模板中 我想显示最后一次登录 Last Login user last seen last seen应该是 sqlite 中的日期时间对象 它总是给我这样的东西 2014 07 27 23 09 36 467761 在模板
  • 卡桑德拉更新专栏

    我如何更新 cassandra 数据库中的列 columnfam username name edds surname surname email email protected 例如我需要更新姓氏 我使用 PHP 客户端 PHPCASSA
  • 当函数是 lambda 或嵌套函数时,concurrent.futures.ProcessPoolExecutor 会挂起

    任何人都可以深入了解为什么使用 lambda 或嵌套函数 f 将使concurrent futures ProcessPoolExecutor挂在下面的代码示例中吗 import concurrent futures def f2 s re
  • 为什么 postgres 的日期范围上限函数返回独占边界?

    我为这篇文章创建了一个 sql 小提琴 http sqlfiddle com 15 7b5d7 1 0 问题 1 为什么插入一条记录时会出现daterange具有独占边界的实际上存储了具有包含下限和独占上限的范围 为什么 pg 不将它们都存
  • C 函数分配不正确的浮点值

    我试图返回一个浮点值并将其分配给一个浮点变量 但新浮点值与返回的值不同 float getVoltageReading return 1 2f void updateUIReadings uint8 t menuID float integ
  • IOS 10 宽色:我需要担心吗?

    The 发行说明iOS 10 有一个标题为广色域 让我感到困惑的是这一行 如果您的应用程序依赖 UIKit 来限制组件值 无论您是创建颜色还是询问颜色的组件值 则在链接到 iOS 10 时 您需要更改应用程序的行为 钳位元件值是什么意思 这
  • 无法找到或加载主类 org.gradle.wrapper.GradleWrapperMain

    我通过删除本地目录来清理整个项目 例如 gradle m2 android and workspace project gradle并选择File gt Invalidate Caches Restart 在 Android Studio
  • 地理编码 API 超出速率限制

    我正在使用地理编码 API 来查询一组 10 万用户的位置坐标 但是 由于速率限制 我每天无法触发超过 2500 个请求 为了我的学习目的 我需要不受限制的访问 这是我大学的一个项目 有人可以引导我走向正确的方向吗 Per the 使用限制
  • 非委托类型的事件

    我已经实现了一个类似于此接口的类 ImmutableObject true public interface ICustomEvent void Invoke object sender EventArgs e ICustomEvent C
  • 增加 C/C++ 程序使用的(非堆栈)内存

    我正在具有 12 GB RAM 的 Windows 操作系统上运行内存密集型作业 根据我的计算 4 GB 内存应该足以运行该程序 我正在运行我用动态内存分配编写的程序 我有两个版本的 C 和 C 程序 malloc free and new
  • python参数类型提示支持嵌套类型信息吗?

    我有一个逻辑如下的函数 def computeProbability x i np array np int32 colProbabilities list dict string np float32 gt list double ret
  • AngularJs图像上传到S3

    I am 创建网络应用程序 带有 ng 文件上传功能的 AngularJS 前端 https github com danialfarid ng file upload Node js 后端 希望能够将图像上传到我的 Amazon S3 存