在Web应用程序上工作时,我将图像文件从浏览器直接转到S3存储桶。这适用于Chrome,但在Safari中没有错误,但代码最终会将空文件上传到S3存储桶。一切基本上看起来都适用于Safari,S3服务器甚至返回204
成功的http响应,文件看起来像在桶中(但是大小为0字节)。
我进行了调试,blobData
在Chrome中的大小为55747,但在Safari中只有大小47560用于同一图像。另外,我发现在网络部分开发工具中看起来略有不同:
Chrome - 正在工作(204响应的正面大小为~534B):
Safari - 不使用空文件(大小列只显示虚线)
这是JS上传代码:
function uploadFile(data_url, s3Data, url, filename, id, thumbnail_url){
var xhr = new XMLHttpRequest();
xhr.open("POST", s3Data.url);
var postData = new FormData();
for(key in s3Data.fields){
postData.append(key, s3Data.fields[key]);
}
var blobData = dataURItoBlob(data_url);
postData.append('file', new File([blobData], filename));
xhr.onreadystatechange = function() {
if(xhr.readyState === 4){
if(xhr.status === 200 || xhr.status === 204){
setTimeout(function(){
$('#photo_container').append('<div id="image_container_'+id+'" class="hover-card mdl-cell--3-col-desktop mdl-cell--2-col-tablet mdl-cell--2-col-phone mdl-shadow--2dp"></div>');
$('.star-image').unbind('click').click( star_image_click );
$('.close-image').unbind('click').click(remove_image_click);
loading_files -= 1;
if ( loading_files == 0 ) {
$('#photo_load_spinner').removeClass('is-active');
$('#photo_load_text').text("");
}else{
$('#photo_load_text').text(loading_files+" files loading. Please wait.");
}
}, 1000);
}else{
alert("Could not upload file. "+xhr.responseText);
}
}
};
xhr.send(postData);
}
function dataURItoBlob(dataURI) {
var binary = atob(dataURI.split(',')[1]);
var array = [];
for(var i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], {type: 'image/png'});
}
我有点不知道下一步要找什么。任何帮助将不胜感激。谢谢!
修改
请注意,我应该提供更多信息。 data_url
是从canvas元素生成的,我用它在浏览器中调整图像大小,虽然我已经确认画布在上传之前在safari中正确显示图像。这是代码:
function ResizeFile(raw_file) {
var reader = new FileReader();
reader.onload = function(e) {
var img = document.createElement("img");
img.onload = function() {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
//ctx.drawImage(img, 0, 0);
var MAX = 1200;
var width = img.width;
var height = img.height;
if (width > height) {
if (width > MAX) {
height *= MAX / width;
width = MAX;
}
} else {
if (height > MAX) {
width *= MAX / height;
height = MAX;
}
}
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, width, height);
var dataurl = canvas.toDataURL("image/png");
getSignedRequest(dataurl);
}
img.src = e.target.result;
}
reader.readAsDataURL(raw_file);
}
答案 0 :(得分:3)
我们可以调整图像文件的大小并上传到服务器。在Chrome和Safari上测试,两者都可以。
fileChange() {
var fileInputTag = document.getElementById("myFile");
if ('files' in fileInputTag) {
if (fileInputTag.files.length > 0) {
var file = fileInputTag.files[0];
var type = 'image/jpeg',
maxWidth = 800,
maxHeight = 600,
quality = 0.5,
ratio = 1,
canvas = document.createElement('canvas'),
context = canvas['getContext']('2d'),
canvasCopy = document.createElement('canvas'),
copyContext = canvasCopy.getContext('2d'),
img = new Image();
img.onload = function () {
if (img.width > maxWidth) {
ratio = maxWidth / img.width;
} else if (img.height > maxHeight) {
ratio = maxHeight / img.height;
}
canvasCopy.width = img.width;
canvasCopy.height = img.height;
copyContext.drawImage(img, 0, 0);
canvas.width = img.width * ratio;
canvas.height = img.height * ratio;
context.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvas.width, canvas.height);
canvas.toBlob((blob) => {
blob['name'] = file.name.split('.')[0] + '.jpeg';
var formData:FormData = new FormData();
formData.append('uploadFile', blob, blob.name);
// do upload here
}, type, quality);
};
img.src = URL.createObjectURL(file);
}
}
}
将此添加到index.html或在上面的脚本执行之前执行
if (!HTMLCanvasElement.prototype.toBlob) {
Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
value: function (callback, type, quality) {
var binStr = atob( this.toDataURL(type, quality).split(',')[1] ),
len = binStr.length,
arr = new Uint8Array(len);
for (var i = 0; i < len; i++ ) {
arr[i] = binStr.charCodeAt(i);
}
callback( new Blob( [arr], {type: type || 'image/png'} ) );
}
});
}
答案 1 :(得分:1)
我记得Safari对FormData对象的支持有限,例如:
https://developer.mozilla.org/en-US/docs/Web/API/FormData/set
https://developer.mozilla.org/en-US/docs/Web/API/FormData/get