草庐IT

javascript - S3 预签名 URL 问题 - 文件上传成功,200 statusCode 但没有响应正文

coder 2024-05-10 原文

这直到最近才有效,我不确定发生了什么变化。我正在使用 S3 SDK 生成一个 presignedUrl 并使用它上传一个文件到一个存储桶。文件实际上传并且响应返回 statusCode 200,但奇怪的是没有响应正文。

我不明白我是否缺少某种标题,或者它们是否有误。响应 header 上的 Content-length 让我担心。

如有任何帮助,我们将不胜感激!

注意:我已经模糊了这些值,如果它们有帮助,我可以将它们模拟回来

一般

请求网址:https://some-bucket.s3.ap-southeast-2.amazonaws.com/some/path/file/picture?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz -凭据=ASIAXXXap-southeast-2%2Fs3%2Faws4_request&X-Amz-Date=xxx&X-Amz-Expires=300&X-Amz-Security-Token=xxx&X-Amz-Signature=xxx&X-Amz-SignedHeaders=host%3Bx-amz-acl&x -amz-acl=公共(public)阅读 请求方法:PUT 状态码:200 OK 远程地址:1.2.3.4:443 推荐人政策:降级时不推荐人

请求 header

接受:application/json, text/plain, */* 接受编码:gzip、deflate、br 接受语言:en-US,en;q=0.9 缓存控制:无缓存 连接:保持事件状态 内容长度:31897 内容类型:图像/jpeg 主机:some-bucket.s3.ap-southeast-2.amazonaws.com 来源:http://localhost:5000 Pragma:无缓存 推荐人:http://localhost:5000/some/page 用户代理:Mozilla/5.0 xxx

响应头

访问控制允许方法:GET、PUT、POST、HEAD 访问控制允许来源:* 内容长度:0 日期:2017 年 5 月 1 日星期四 01:00:00 GMT 电子标签:“xxx” 服务器:AmazonS3 变化:来源、访问控制请求 header 、访问控制请求方法 x-amz-id-2: xxx x-amz-请求-id: xxx

查询字符串参数

X-Amz-算法:AWS4-HMAC-SHA256 X-Amz-凭证:ASIAXXXap-southeast-2/s3/aws4_request X-Amz-日期:XXX X-Amz-过期:300 X-Amz-安全 token :XXX X-Amz-签名:XXX X-Amz-SignedHeaders:主机;x-amz-acl x-amz-acl:公开阅读

预签名服务(NodeJS、Lambda)

... 
const params = {
    Bucket: 'some-bucket',
    Key: 'some/path/file/picture',
    Expires: 60 * 5,
    ACL: 'public-read'
};

s3.getSignedUrl('putObject', params, (err, url) => {
    ...
    callback(null, new Response(200, {url});
});
...

S3 服务(TS、Angular)

public putObject(presignedUrl: string, file: File): Observable<any> {
  return this.http.put<any>(presignedUrl, file);
}

组件

this.s3Service.putObject(presignedUrl, file)
  .subscribe(
    (response) => {
      // it gets here as expected
      // but response is null!
    },
    () => {}
  );

最佳答案

我使用 go SDK 重现了它,以确认它是 API 本身的行为方式,而不是 nodejs 的特定行为。

从我的实验中可以看出,它现在是一种正常行为,它不会从 PUT 请求返回任何内容。

OBS:我屏蔽了一些敏感值!

代码:

package main

import (
    "crypto/tls"
    "fmt"
    "log"
    "net/http"
    "net/url"
    "strings"
    "time"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

func main() {
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String("eu-west-1")},
    )

    svc := s3.New(sess)

    req1, _ := svc.PutObjectRequest(&s3.PutObjectInput{
        Bucket: aws.String("bucketversioningenabled"),
        Key:    aws.String("myKey"),
        Body:   strings.NewReader("EXPECTED CONTENTS"),
    })

    presignURL, err := req1.Presign(time.Minute * 1)
    if err != nil {
        log.Println("Error on presign", err)
        return
    }
    fmt.Println("Presign: ", presignURL, err)
    fmt.Println("")

    req2, err := http.NewRequest("PUT", presignURL, strings.NewReader("EXPECTED CONTENTS"))
    if err != nil {
        log.Println("error creating request", err)
        return
    }
    fmt.Println("NewRequest: ", req2, err)
    fmt.Println("")

    proxyURL, err := url.Parse("http://myfiddler.proxy.com:8888")
    if err != nil {
        log.Println("Error on proxy parse", err)
        return
    }

    tr := &http.Transport{
        TLSClientConfig: &tls.Config{
            InsecureSkipVerify: true,
        },
        Proxy: http.ProxyURL(proxyURL),
    }
    client := &http.Client{
        Transport: tr,
        Timeout:   time.Duration(5 * time.Second),
    }

    resp, err := client.Do(req2)
    if err != nil {
        log.Println("error on request put", err)
        return
    }
    fmt.Println("Do: ", resp, err)
}

执行输出:

请看最后一行的Content-Length:[0]

$ ./s3put 
Presign:  https://bucketversioningenabled.s3.eu-west-1.amazonaws.com/myKey?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=XXXXX%2F20180531%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20180531T112707Z&X-Amz-Expires=60&X-Amz-Security-Token=XXXX&X-Amz-SignedHeaders=content-length%3Bhost&X-Amz-Signature=XXXX <nil>

NewRequest:  &{PUT https://bucketversioningenabled.s3.eu-west-1.amazonaws.com/myKey?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=XXXX%2F20180531%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20180531T112707Z&X-Amz-Expires=60&X-Amz-Security-Token=XXXX&X-Amz-SignedHeaders=content-length%3Bhost&X-Amz-Signature=XXXX HTTP/1.1 1 1 map[] {0xc42010d020} 0x5f2040 17 [] false bucketversioningenabled.s3.eu-west-1.amazonaws.com map[] map[] <nil> map[]   <nil> <nil> <nil> <nil>} <nil>

Do:  &{200 OK 200 HTTP/1.1 1 1 map[X-Amz-Version-Id:[3I4txVUgi4ObULr8EVadA4U3cfvdVwQM] Etag:["952973475e3f4d992fe48578086c1e17"] Content-Length:[0] Server:[AmazonS3] X-Amz-Id-2:[yGUZtjttGKwv0uJxQcG7bIkGRqxhPxKeW71jWIGkmwt73oZY/+r3HWyr2uK07nR8xTDQyzbM3Hw=] X-Amz-Request-Id:[509F1785D0383ADA] Date:[Thu, 31 May 2018 11:27:09 GMT]] 0xc42000c0e0 0 [] false false map[] 0xc42019c400 0xc420199290} <nil>

下面是Fiddler的请求和响应

要求:

PUT https://bucketversioningenabled.s3.eu-west-1.amazonaws.com/myKey?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=XXXX%2F20180531%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20180531T112707Z&X-Amz-Expires=60&X-Amz-Security-Token=XXXX&X-Amz-SignedHeaders=content-length%3Bhost&X-Amz-Signature=XXXX HTTP/1.1
Host: bucketversioningenabled.s3.eu-west-1.amazonaws.com
User-Agent: Go-http-client/1.1
Content-Length: 17
Accept-Encoding: gzip

EXPECTED CONTENTS

响应(查看内容长度):

HTTP/1.1 200 OK
x-amz-id-2: yGUZtjttGKwv0uJxQcG7bIkGRqxhPxKeW71jWIGkmwt73oZY/+r3HWyr2uK07nR8xTDQyzbM3Hw=
x-amz-request-id: 509F1785D0383ADA
Date: Thu, 31 May 2018 11:27:09 GMT
x-amz-version-id: 3I4txVUgi4ObULr8EVadA4U3cfvdVwQM
ETag: "952973475e3f4d992fe48578086c1e17"
Content-Length: 0
Server: AmazonS3

关于javascript - S3 预签名 URL 问题 - 文件上传成功,200 statusCode 但没有响应正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50503855/

有关javascript - S3 预签名 URL 问题 - 文件上传成功,200 statusCode 但没有响应正文的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  3. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  4. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  5. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  8. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  9. ruby-on-rails - rails : save file from URL and save it to Amazon S3 - 2

    从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex

  10. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

随机推荐