Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过预先签名的URL将文件上载到AWS S3时Javascript不工作_Javascript_Python_Amazon Web Services_Amazon S3 - Fatal编程技术网

通过预先签名的URL将文件上载到AWS S3时Javascript不工作

通过预先签名的URL将文件上载到AWS S3时Javascript不工作,javascript,python,amazon-web-services,amazon-s3,Javascript,Python,Amazon Web Services,Amazon S3,我生成一个预签名的URL,用于通过Python支持的API将文件上载到AWS S3。一旦用户在浏览器中选择文件(见下文),此部分将接收文件名信息,并返回带有基本URL和字段的JSON有效负载(见下文) 导入日志 进口boto3 从botocore.exceptions导入ClientError def create_presigned_post(桶名称、对象名称、, 字段=无,条件=无,过期=3600): #生成预先签名的S3 POST URL s3\u client=boto3.client(

我生成一个预签名的URL,用于通过Python支持的API将文件上载到AWS S3。一旦用户在浏览器中选择文件(见下文),此部分将接收文件名信息,并返回带有基本URL和字段的JSON有效负载(见下文)

导入日志
进口boto3
从botocore.exceptions导入ClientError
def create_presigned_post(桶名称、对象名称、,
字段=无,条件=无,过期=3600):
#生成预先签名的S3 POST URL
s3\u client=boto3.client('s3'))
尝试:
response=s3\u client.generate\u presigned\u post(bucket\u name,
对象名称,
字段=字段,
条件=条件,
ExpiresIn=到期日)
除ClientError作为e外:
logging.error(e)
一无所获
#响应包含预先签名的URL和必填字段
返回响应
下面是我从这个函数得到的JSON响应。(我更改/缩写了一些值,但你明白了。)

{
“url”:”https://s3.us-east-2.amazonaws.com/my_bucket_name",
“字段”:{
“key”:“some.txt”,
“AWSAccessKeyId”:“ASI…”,
“x-amz-security-token”:“Ag9o…”,
“政策”:“eyJ…=”,
“签名”:“jn…”
}
}
这是我用来上传文件的HTML表单。我有一些普通的Javascript,可以跟踪表单的更改,并在更改时更新表单的
URL\u值
,以及每个表单项的
(例如,文件选择)


文件:

这个HTML表单本身工作得很好,但我尝试添加一些Javascript(香草和JQuery),这样我就可以跟踪文件进度并禁用表单输入,直到上传完成

我无法让Javascript工作

我已经尝试了很多例子(同样,香草JS和JQuery)


最近是否有人实施了此功能并能提供帮助?

我相信您必须传递AWS机密,例如

"key": "some.txt",
    "AWSAccessKeyId": "ASI...",
    "x-amz-security-token": "Ag9o...",
    "policy": "eyJ...=",
    "signature": "jn...="
作为标题

您正在使用
fetch
库吗? 你能把JS代码发布到吗?

好的,我找到了一个普通的JS示例


$(文档).ready(函数(){
var PRESIGNED_URL=“”
$('input[type=“file”]”)。更改(函数(e){
var fileName=e.target.files[0]。名称;
变量设置={
“异步”:true,
“跨域”:正确,
“url”:”https://my_api.com",
“方法”:“发布”,
“标题”:{
“内容类型”:“应用程序/x-www-form-urlencoded”,
},
“数据”:{
“文件名”:文件名
}
}
$.ajax(设置).done(函数(响应){
$(“#文件名”).html(文件名)
预签名的URL=响应[“URL”]
$(“#表单”).attr(“操作”,响应[“url]”)
$(“#键”).val(响应[“字段”][“键”])
$(“#AWSAccessKeyId”).val(响应[“字段”][“AWSAccessKeyId”])
$(“#策略”).val(响应[“字段”][“策略”])
$(“#签名”).val(响应[“字段”][“签名”])
$(“#x-amz-security-token”).val(响应[“字段”][“x-amz-security-token”])
返回
});
});
$(“#按钮”)。在(“单击”上,函数(e){
var form=document.getElementById('form');
var formData=新formData(表格);
var xhr=new XMLHttpRequest();
//在此处添加任何事件处理程序。。。
xhr.upload.addEventListener('progress',函数(e){
var完成百分比=(e.loaded/e.total)*100;
//已完成上载的百分比
控制台日志(完成百分比);
});
xhr.onloadstart=函数(e){
console.log(“开始”)
}
xhr.onloadend=函数(e){
控制台日志(“结束”)
}
xhr.open('POST',PRESIGNED_URL,true);
xhr.send(formData);
$(“#文件名”).html(“”)
})
});
有这么多相近的变化,但这对工作完美


(我相信这对很多人来说是显而易见的,但我只是在必要时做前端开发…

这比你发布的内容更容易

fetch(yourSignedUrl, {
  method: 'PUT',
  body: file,
  headers: {
    'Content-Type': file.type
  }
}).then((res) => {
  if (!res.ok) {
    throw new Error(res.statusText);
  }
  return res.headers.get('ETag');
});

我收到的错误消息多种多样:
禁止
访问被拒绝
错误请求
格式错误的请求
。。。。大多数情况下,403和412状态代码都是这样的,但由于某种原因,当我通过JS发送它们时,它不喜欢这样。通过Python发布文件作为原始API测试时,工作正常。顺便说一下,我没有发布JS,因为我确实尝试了十几种JQuery/vanilla JS变体。。。感谢您的回答,虽然这显然是JQuery和vanilla JS的混合,但同样失败的部分是底部附近的POST请求。喜欢当我可以用简单的旧JS写东西的时候。根本不需要这个表单和所有其他的东西。看看我的答案。。。您可以直接使用预签名的PUT URL。我将尝试使用PUT,但指定预签名的URL将只接受POST这根本不是真的。。。您正在查看表单上载。您可以使用PUT方法生成URL。看起来您想要的是类似于
create\u presigned\u url\u expanded('put\u object',…)
好的,还没有尝试使用presigned url的put object client方法。。。我使用PUT将标准文件上传到S3,所以这很有意义。我只是在用包裹邮寄的方法。酷,我得到了一个403错误的约会。。。响应提供了基本URL,我尝试将其编码为查询字符串,并将其连接在一个长字符串中URL@openwonk哦,我明白了,问题是你实际上没有生成一个完整的预签名URL。我对Py不熟悉