Node.js 无法从AWS s3上的浏览器上载文件
我正在尝试将数据上载到AWS S3。如果我给出Node.js 无法从AWS s3上的浏览器上载文件,node.js,amazon-web-services,amazon-s3,Node.js,Amazon Web Services,Amazon S3,我正在尝试将数据上载到AWS S3。如果我给出内容类型:false,我会得到一个错误: At least one of the pre-conditions you specified did not hold</Message><Condition>Bucket POST must be of the enclosure-type multipart/form-data</Condition> 我被困在这个问题上很长时间了,任何帮助都将不胜感激。 为了生成
内容类型:false
,我会得到一个错误:
At least one of the pre-conditions you specified did not hold</Message><Condition>Bucket POST must be of the enclosure-type multipart/form-data</Condition>
我被困在这个问题上很长时间了,任何帮助都将不胜感激。
为了生成签名
和策略
,我遵循了以下博客:
以下是相关代码(如果url将来不再可用):
您不想使用AWS JavaScript SDK有什么原因吗?@jarmod您好,我不想在前端公开accessKey和secretKey我不知道我是否理解。您现有的代码已经需要access key和secret key来签署请求。@jarmod是的,但我正在服务器上这样做。据我所知,如果我使用AWS SDK,我需要在前端保存密钥,或者先将文件上载到服务器,然后再上载到AWS。如果您有服务器组件,则您的网页可以从服务器组件请求预签名的S3上载URL。然后,该网页可以将文件直接上载到该URL,而无需进一步验证。
const file = document.getElementById('file').files[0];
// let data = e.target;
const filename = file.name;
const contentType = file.type;
const params = [];
const self = this;
$.ajax({
url: self.credentialsUrl,
type: "GET",
dataType: "json",
data: {
filename: filename,
content_type: contentType
},
success: function(s3Data) {
const formData = s3Data.params;
formData["file"] = file;
$.ajax({
type: "POST",
url: s3Data.endpoint_url,
data: formData,
dataType: "xml",
contentType: false,
processData:false,
success: function(resultData){
console.log(resultData);
},
error: function(error){
console.log(error);
}
});
}
});
var crypto = require('crypto');
// This is the entry function that produces data for the frontend
// config is hash of S3 configuration:
// * bucket
// * region
// * accessKey
// * secretKey
function s3Credentials(config, filename) {
return {
endpoint_url: "https://" + config.bucket + ".s3.amazonaws.com",
params: s3Params(config, filename)
}
}
// Returns the parameters that must be passed to the API call
function s3Params(config, filename) {
var credential = amzCredential(config);
var policy = s3UploadPolicy(config, filename, credential);
var policyBase64 = new Buffer(JSON.stringify(policy)).toString('base64');
return {
key: filename,
acl: 'public-read',
success_action_status: '201',
policy: policyBase64,
'x-amz-algorithm': 'AWS4-HMAC-SHA256',
'x-amz-credential': credential,
'x-amz-date': dateString() + 'T000000Z',
'x-amz-signature': s3UploadSignature(config, policyBase64, credential)
}
}
function dateString() {
var date = new Date().toISOString();
return date.substr(0, 4) + date.substr(5, 2) + date.substr(8, 2);
}
function amzCredential(config) {
return [config.accessKey, dateString(), config.region, 's3/aws4_request'].join('/')
}
// Constructs the policy
function s3UploadPolicy(config, filename, credential) {
return {
// 5 minutes into the future
expiration: new Date((new Date).getTime() + (5 * 60 * 1000)).toISOString(),
conditions: [
{ bucket: config.bucket },
{ key: filename },
{ acl: 'public-read' },
{ success_action_status: "201" },
// Optionally control content type and file size
// {'Content-Type': 'application/pdf'},
['content-length-range', 0, 1000000],
{ 'x-amz-algorithm': 'AWS4-HMAC-SHA256' },
{ 'x-amz-credential': credential },
{ 'x-amz-date': dateString() + 'T000000Z' }
],
}
}
function hmac(key, string) {
var hmac = require('crypto').createHmac('sha256', key);
hmac.end(string);
return hmac.read();
}
// Signs the policy with the credential
function s3UploadSignature(config, policyBase64, credential) {
var dateKey = hmac('AWS4' + config.secretKey, dateString());
var dateRegionKey = hmac(dateKey, config.region);
var dateRegionServiceKey = hmac(dateRegionKey, 's3');
var signingKey = hmac(dateRegionServiceKey, 'aws4_request');
return hmac(signingKey, policyBase64).toString('hex');
}
module.exports = {
s3Credentials: s3Credentials
}