Ruby Shrine - 裁剪和直接上传 Safari 问题
Ruby Shrine - crop & direct upload Safari issue
我正在使用 Shrine 实现直接上传,jquery.fileupload 和 cropper.js
在 add 部分,我从文件上传到模态加载图像,定义裁剪器并显示模态
if (data.files && data.files[0]) {
var reader = new FileReader();
var $preview = $('#preview_avatar');
reader.onload = function(e) {
$preview.attr('src', e.target.result); // insert preview image
$preview.cropper({
dragMode: 'move',
aspectRatio: 1.0 / 1.0,
autoCropArea: 0.65,
data: {width: 270, height: 270}
})
};
reader.readAsDataURL(data.files[0]);
$('#crop_modal').modal('show', {
backdrop: 'static',
keyboard: false
});
}
然后在模式按钮上单击我得到裁剪 canvas 调用它 toBlob 并提交到 S3
$('#crop_button').on('click', function(){
var options = {
extension: data.files[0].name.match(/(\.\w+)?$/)[0], // set extension
_: Date.now() // prevent caching
};
var canvas = $preview.cropper('getCroppedCanvas');
$.getJSON('/images/cache/presign', options).
then(function (result) {
data.formData = result['fields'];
data.url = result['url'];
data.paramName = 'file';
if (canvas.toBlob) {
canvas.toBlob(
function (blob) {
var file = new File([blob], 'cropped_file.jpeg');
console.log('file', file);
data.files[0] = file;
data.originalFiles[0] = data.files[0];
data.submit();
},
'image/jpeg'
);
}
});
});
上传到 S3 完成后,我将图像属性写入隐藏字段,关闭模式并销毁裁剪器
done: function (e, data) {
var image = {
id: data.formData.key.match(/cache\/(.+)/)[1], // we have to remove the prefix part
storage: 'cache',
metadata: {
size: data.files[0].size,
filename: data.files[0].name.match(/[^\/\]*$/)[0], // IE returns full path
// mime_type: data.files[0].type
mime_type: 'image/jpeg'
}
};
console.log('image', image);
$('.cached-avatar').val(JSON.stringify(image));
$('#crop_modal').modal('hide');
$('#preview_avatar').cropper('destroy');
}
chrome 一开始一切正常,但后来我发现 safari 没有 toBlob 功能。
我找到了这个:
https://github.com/blueimp/JavaScript-Canvas-to-Blob
而 toBlob 不是函数错误消失了..
由于某些与 MIME 类型相关的问题,现在我无法保存图像。
我能够找到它在 safari 上失败的确切位置,但找不到 chrome.
determine_mime_type.rb 第 142 行
在 options = {stdin_data: io.read(MAGIC_NUMBER), binmode: true}
中的第 139 行
stdin_data 在 io.read
之后为空
有什么想法吗?
谢谢!
更新
我能够弄清楚 url 到
返回的缓存图像
$.getJSON('/images/cache/presign', options)
returns 从 safari 裁剪和上传时的空文件。
因此,正如我在问题中提到的,一旦被 cropper.js 裁剪,safari 就会上传空文件。
问题显然源于此块:
if (canvas.toBlob) {
canvas.toBlob(
function (blob) {
var file = new File([blob], 'cropped_file.jpeg');
console.log('file', file);
data.files[0] = file;
data.originalFiles[0] = data.files[0];
data.submit();
},
'image/jpeg'
);
}
我在对我读过的一篇文章的评论中发现,safari 做了一些类似 "file.toString" 的事情,在我的例子中导致空文件上传。
我直接附加了 blob,而没有先从它创建文件,一切正常。
if (canvas.toBlob) {
canvas.toBlob(
function (blob) {
data.files[0] = blob;
data.files[0].name = 'cropped_file.jpeg';
data.files[0].type = 'image/jpeg';
data.originalFiles[0] = data.files[0];
data.submit();
},
'image/jpeg'
);
}
我正在使用 Shrine 实现直接上传,jquery.fileupload 和 cropper.js
在 add 部分,我从文件上传到模态加载图像,定义裁剪器并显示模态
if (data.files && data.files[0]) {
var reader = new FileReader();
var $preview = $('#preview_avatar');
reader.onload = function(e) {
$preview.attr('src', e.target.result); // insert preview image
$preview.cropper({
dragMode: 'move',
aspectRatio: 1.0 / 1.0,
autoCropArea: 0.65,
data: {width: 270, height: 270}
})
};
reader.readAsDataURL(data.files[0]);
$('#crop_modal').modal('show', {
backdrop: 'static',
keyboard: false
});
}
然后在模式按钮上单击我得到裁剪 canvas 调用它 toBlob 并提交到 S3
$('#crop_button').on('click', function(){
var options = {
extension: data.files[0].name.match(/(\.\w+)?$/)[0], // set extension
_: Date.now() // prevent caching
};
var canvas = $preview.cropper('getCroppedCanvas');
$.getJSON('/images/cache/presign', options).
then(function (result) {
data.formData = result['fields'];
data.url = result['url'];
data.paramName = 'file';
if (canvas.toBlob) {
canvas.toBlob(
function (blob) {
var file = new File([blob], 'cropped_file.jpeg');
console.log('file', file);
data.files[0] = file;
data.originalFiles[0] = data.files[0];
data.submit();
},
'image/jpeg'
);
}
});
});
上传到 S3 完成后,我将图像属性写入隐藏字段,关闭模式并销毁裁剪器
done: function (e, data) {
var image = {
id: data.formData.key.match(/cache\/(.+)/)[1], // we have to remove the prefix part
storage: 'cache',
metadata: {
size: data.files[0].size,
filename: data.files[0].name.match(/[^\/\]*$/)[0], // IE returns full path
// mime_type: data.files[0].type
mime_type: 'image/jpeg'
}
};
console.log('image', image);
$('.cached-avatar').val(JSON.stringify(image));
$('#crop_modal').modal('hide');
$('#preview_avatar').cropper('destroy');
}
chrome 一开始一切正常,但后来我发现 safari 没有 toBlob 功能。
我找到了这个:
https://github.com/blueimp/JavaScript-Canvas-to-Blob
而 toBlob 不是函数错误消失了..
由于某些与 MIME 类型相关的问题,现在我无法保存图像。
我能够找到它在 safari 上失败的确切位置,但找不到 chrome.
determine_mime_type.rb 第 142 行
在 options = {stdin_data: io.read(MAGIC_NUMBER), binmode: true}
中的第 139 行
stdin_data 在 io.read
有什么想法吗?
谢谢!
更新
我能够弄清楚 url 到
$.getJSON('/images/cache/presign', options)
returns 从 safari 裁剪和上传时的空文件。
因此,正如我在问题中提到的,一旦被 cropper.js 裁剪,safari 就会上传空文件。
问题显然源于此块:
if (canvas.toBlob) {
canvas.toBlob(
function (blob) {
var file = new File([blob], 'cropped_file.jpeg');
console.log('file', file);
data.files[0] = file;
data.originalFiles[0] = data.files[0];
data.submit();
},
'image/jpeg'
);
}
我在对我读过的一篇文章的评论中发现,safari 做了一些类似 "file.toString" 的事情,在我的例子中导致空文件上传。
我直接附加了 blob,而没有先从它创建文件,一切正常。
if (canvas.toBlob) {
canvas.toBlob(
function (blob) {
data.files[0] = blob;
data.files[0].name = 'cropped_file.jpeg';
data.files[0].type = 'image/jpeg';
data.originalFiles[0] = data.files[0];
data.submit();
},
'image/jpeg'
);
}