通过 Lambda 和 API 网关从 AWS S3 下载图像——使用 fetch class
Downloading images form AWS S3 via Lambda and API Gateway--using fetch class
我正在尝试使用 JavaScript fetch API, AWS API Gateway, AWS Lambda, and AWS S3 创建允许用户上传和下载媒体的服务。服务器正在使用 NodeJs 8.10;浏览器是 Google Chrome 版本 69.0.3497.92(官方构建)(64 位)。
从长远来看,允许的媒体将包括音频、视频和图像。现在,我很乐意让图像正常工作。
我遇到的问题:我的 browser-side 客户端使用 fetch 实现,能够通过 API 网关和 Lambda 将 JPEG 上传到 S3 就好了。我可以使用 curl
或 S3 控制台从我的 S3 存储桶下载 JPEG,然后在图像查看器中查看图像就好了。
但是,如果我尝试通过 browser-side 客户端下载图像并获取,我无法在浏览器中显示任何内容。
这是来自 browser-side 客户端的代码:
fetch(
'path/to/resource',
{
method: 'post',
mode: "cors",
body: an_instance_of_file_from_an_html_file_input_tag,
headers: {
Authorization: user_credentials,
'Content-Type': 'image/jpeg',
},
}
).then((response) => {
return response.blob();
}).then((blob) => {
const img = new Image();
img.src = URL.createObjectURL(blob);
document.body.appendChild(img);
}).catch((error) => {
console.error('upload failed',error);
});
这是 server-side 代码,使用 Claudia.js:
const AWS = require('aws-sdk');
const ApiBuilder = require('claudia-api-builder');
const api = new ApiBuilder();
api.corsOrigin(allowed_origin);
api.registerAuthorizer('my authorizer', {
providerARNs: ['arn of my cognito user pool']
});
api.get(
'/media',
(request) => {
'use strict';
const s3 = new AWS.S3();
const params = {
Bucket: 'name of my bucket',
Key: 'name of an object that is confirmed to exist in the bucket and to be properly encoded as and readable as a JPEG',
};
return s3.getObject(params).promise().then((response) => {
return response.Body;
})
;
}
);
module.exports = api;
这是 Chrome 的网络面板中的初始 OPTION
请求和响应 headers:
这是随后的 GET
请求和响应 headers:
我感兴趣的是,图像大小在 S3 控制台中报告为 699873(没有单位),但 GET 事务的响应 body 在 Chrome 中报告为大约2.5 MB(同样,没有单位)。
生成的图像是一个 16x16 正方形并且死了 link。我在浏览器的控制台或 CloudWatch 中没有收到任何错误或警告。
我已经尝试了很多东西;很想听听外面的人能想出什么。
提前致谢。
编辑:在 Chrome:
Claudia 要求客户端指定它将在二进制负载上接受的 MIME 类型。因此,将 'Content-type'
配置保留在 headers
对象客户端中:
fetch(
'path/to/resource',
{
method: 'post',
mode: "cors",
body: an_instance_of_file_from_an_html_file_input_tag,
headers: {
Authorization: user_credentials,
'Content-Type': 'image/jpeg', // <-- This is important.
},
}
).then((response) => {
return response.blob();
}).then((blob) => {
const img = new Image();
img.src = URL.createObjectURL(blob);
document.body.appendChild(img);
}).catch((error) => {
console.error('upload failed',error);
});
然后,在服务器端,您需要告诉 Claudia 响应应该是二进制的,以及要使用哪种 MIME 类型:
const AWS = require('aws-sdk');
const ApiBuilder = require('claudia-api-builder');
const api = new ApiBuilder();
api.corsOrigin(allowed_origin);
api.registerAuthorizer('my authorizer', {
providerARNs: ['arn of my cognito user pool']
});
api.get(
'/media',
(request) => {
'use strict';
const s3 = new AWS.S3();
const params = {
Bucket: 'name of my bucket',
Key: 'name of an object that is confirmed to exist in the bucket and to be properly encoded as and readable as a JPEG',
};
return s3.getObject(params).promise().then((response) => {
return response.Body;
})
;
},
/** Add this. **/
{
success: {
contentType: 'image/jpeg',
contentHandling: 'CONVERT_TO_BINARY',
},
}
);
module.exports = api;
我正在尝试使用 JavaScript fetch API, AWS API Gateway, AWS Lambda, and AWS S3 创建允许用户上传和下载媒体的服务。服务器正在使用 NodeJs 8.10;浏览器是 Google Chrome 版本 69.0.3497.92(官方构建)(64 位)。
从长远来看,允许的媒体将包括音频、视频和图像。现在,我很乐意让图像正常工作。
我遇到的问题:我的 browser-side 客户端使用 fetch 实现,能够通过 API 网关和 Lambda 将 JPEG 上传到 S3 就好了。我可以使用 curl
或 S3 控制台从我的 S3 存储桶下载 JPEG,然后在图像查看器中查看图像就好了。
但是,如果我尝试通过 browser-side 客户端下载图像并获取,我无法在浏览器中显示任何内容。
这是来自 browser-side 客户端的代码:
fetch(
'path/to/resource',
{
method: 'post',
mode: "cors",
body: an_instance_of_file_from_an_html_file_input_tag,
headers: {
Authorization: user_credentials,
'Content-Type': 'image/jpeg',
},
}
).then((response) => {
return response.blob();
}).then((blob) => {
const img = new Image();
img.src = URL.createObjectURL(blob);
document.body.appendChild(img);
}).catch((error) => {
console.error('upload failed',error);
});
这是 server-side 代码,使用 Claudia.js:
const AWS = require('aws-sdk');
const ApiBuilder = require('claudia-api-builder');
const api = new ApiBuilder();
api.corsOrigin(allowed_origin);
api.registerAuthorizer('my authorizer', {
providerARNs: ['arn of my cognito user pool']
});
api.get(
'/media',
(request) => {
'use strict';
const s3 = new AWS.S3();
const params = {
Bucket: 'name of my bucket',
Key: 'name of an object that is confirmed to exist in the bucket and to be properly encoded as and readable as a JPEG',
};
return s3.getObject(params).promise().then((response) => {
return response.Body;
})
;
}
);
module.exports = api;
这是 Chrome 的网络面板中的初始 OPTION
请求和响应 headers:
这是随后的 GET
请求和响应 headers:
我感兴趣的是,图像大小在 S3 控制台中报告为 699873(没有单位),但 GET 事务的响应 body 在 Chrome 中报告为大约2.5 MB(同样,没有单位)。
生成的图像是一个 16x16 正方形并且死了 link。我在浏览器的控制台或 CloudWatch 中没有收到任何错误或警告。
我已经尝试了很多东西;很想听听外面的人能想出什么。
提前致谢。
编辑:在 Chrome:
Claudia 要求客户端指定它将在二进制负载上接受的 MIME 类型。因此,将 'Content-type'
配置保留在 headers
对象客户端中:
fetch(
'path/to/resource',
{
method: 'post',
mode: "cors",
body: an_instance_of_file_from_an_html_file_input_tag,
headers: {
Authorization: user_credentials,
'Content-Type': 'image/jpeg', // <-- This is important.
},
}
).then((response) => {
return response.blob();
}).then((blob) => {
const img = new Image();
img.src = URL.createObjectURL(blob);
document.body.appendChild(img);
}).catch((error) => {
console.error('upload failed',error);
});
然后,在服务器端,您需要告诉 Claudia 响应应该是二进制的,以及要使用哪种 MIME 类型:
const AWS = require('aws-sdk');
const ApiBuilder = require('claudia-api-builder');
const api = new ApiBuilder();
api.corsOrigin(allowed_origin);
api.registerAuthorizer('my authorizer', {
providerARNs: ['arn of my cognito user pool']
});
api.get(
'/media',
(request) => {
'use strict';
const s3 = new AWS.S3();
const params = {
Bucket: 'name of my bucket',
Key: 'name of an object that is confirmed to exist in the bucket and to be properly encoded as and readable as a JPEG',
};
return s3.getObject(params).promise().then((response) => {
return response.Body;
})
;
},
/** Add this. **/
{
success: {
contentType: 'image/jpeg',
contentHandling: 'CONVERT_TO_BINARY',
},
}
);
module.exports = api;