问题描述
6 年后,jQuery 文件上传显然仍然让人们发疯.如果您在此处的答案中发现一点安慰,请尝试 搜索 NPM 现代替代品.这不值得麻烦,我保证.
6 years later and jQuery File Upload is clearly still driving folks insane. If you're finding little solace in the answers here, try a search of NPM for a modern alternative. It's not worth the hassle, I promise.
我在之前的编辑中推荐了 Uploadify,但正如评论者指出的那样,他们似乎不再提供免费版本.无论如何,Uploadify 所以 2013 年.
I recommended Uploadify in the previous edit but, as a commenter pointed out, they no longer appear to offer a free version. Uploadify was so 2013 anyway.
我正在尝试使用 blueimp 的 jQuery 文件上传 来允许用户上传文件.开箱即用,按照设置说明进行操作.但要在我的网站上实际使用它,我希望能够做一些事情:
I'm trying to use blueimp's jQuery File Upload to allow users to upload files. Out of the box it works perfectly, following the setup instructions. But to use it practically on my website, I want to be able to do a couple of things:
- 在我现有的任何页面上包含上传器
- 更改上传文件的目录
插件的所有文件都位于根目录下的文件夹中.
All the files for the plugin are located in a folder under the root.
- 将演示页面移至根目录并更新必要脚本的路径
- 按照建议更改 UploadHandler.php 文件中的upload_dir"和upload_url"选项 此处.
- 更改演示 javascript 第二行中的 URL
在所有情况下,预览显示,进度条运行,但文件上传失败,我在控制台中收到此错误:Uncaught TypeError: Cannot read property 'files' of undefined
.我不明白插件的所有部分是如何工作的,这使得调试变得困难.
In all cases, the preview shows, and the progress bar runs, but the files fail to upload, and I get this error in the console: Uncaught TypeError: Cannot read property 'files' of undefined
. I don't understand how all the parts of the plugin work which is making it difficult to debug.
演示页面中的javascript:
The javascript in the demo page:
$(function () {
'use strict';
// Change this to the location of your server-side upload handler:
var url = 'file_upload/server/php/UploadHandler.php',
uploadButton = $('<button/>')
.addClass('btn')
.prop('disabled', true)
.text('Processing...')
.on('click', function () {
var $this = $(this),
data = $this.data();
$this
.off('click')
.text('Abort')
.on('click', function () {
$this.remove();
data.abort();
});
data.submit().always(function () {
$this.remove();
});
});
$('#fileupload').fileupload({
url: url,
dataType: 'json',
autoUpload: false,
acceptFileTypes: /(.|/)(gif|jpe?g|png)$/i,
maxFileSize: 5000000, // 5 MB
// Enable image resizing, except for Android and Opera,
// which actually support image resizing, but fail to
// send Blob objects via XHR requests:
disableImageResize: /Android(?!.*Chrome)|Opera/
.test(window.navigator.userAgent),
previewMaxWidth: 100,
previewMaxHeight: 100,
previewCrop: true
}).on('fileuploadadd', function (e, data) {
data.context = $('<div/>').appendTo('#files');
$.each(data.files, function (index, file) {
var node = $('<p/>')
.append($('<span/>').text(file.name));
if (!index) {
node
.append('<br>')
.append(uploadButton.clone(true).data(data));
}
node.appendTo(data.context);
});
}).on('fileuploadprocessalways', function (e, data) {
var index = data.index,
file = data.files[index],
node = $(data.context.children()[index]);
if (file.preview) {
node
.prepend('<br>')
.prepend(file.preview);
}
if (file.error) {
node
.append('<br>')
.append(file.error);
}
if (index + 1 === data.files.length) {
data.context.find('button')
.text('Upload')
.prop('disabled', !!data.files.error);
}
}).on('fileuploadprogressall', function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .bar').css(
'width',
progress + '%'
);
}).on('fileuploaddone', function (e, data) {
$.each(data.result.files, function (index, file) {
var link = $('<a>')
.attr('target', '_blank')
.prop('href', file.url);
$(data.context.children()[index])
.wrap(link);
});
}).on('fileuploadfail', function (e, data) {
$.each(data.result.files, function (index, file) {
var error = $('<span/>').text(file.error);
$(data.context.children()[index])
.append('<br>')
.append(error);
});
}).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');
});
我对缺乏文档感到惊讶;看起来改变应该是一件简单的事情.如果有人能解释如何做到这一点,我将不胜感激.
I'm surprised by the lack of documentation; it seems like it should be a simple thing to change. I would appreciate if someone could explain how to do this.
推荐答案
几天前我正在寻找类似的功能,并在 tutorialzine 上找到了一个很好的教程.这是一个工作示例.可以在此处找到完整的教程.
I was looking for a similar functionality some days back and came across a good tutorial on tutorialzine. Here is an working example. Complete tutorial can be found here.
保存文件上传对话框的简单表格:
Simple form to hold the file upload dialogue:
<form id="upload" method="post" action="upload.php" enctype="multipart/form-data">
<input type="file" name="uploadctl" multiple />
<ul id="fileList">
<!-- The file list will be shown here -->
</ul>
</form>
这里是上传文件的jQuery代码:
And here is the jQuery code to upload the files:
$('#upload').fileupload({
// This function is called when a file is added to the queue
add: function (e, data) {
//This area will contain file list and progress information.
var tpl = $('<li class="working">'+
'<input type="text" value="0" data-width="48" data-height="48" data-fgColor="#0788a5" data-readOnly="1" data-bgColor="#3e4043" />'+
'<p></p><span></span></li>' );
// Append the file name and file size
tpl.find('p').text(data.files[0].name)
.append('<i>' + formatFileSize(data.files[0].size) + '</i>');
// Add the HTML to the UL element
data.context = tpl.appendTo(ul);
// Initialize the knob plugin. This part can be ignored, if you are showing progress in some other way.
tpl.find('input').knob();
// Listen for clicks on the cancel icon
tpl.find('span').click(function(){
if(tpl.hasClass('working')){
jqXHR.abort();
}
tpl.fadeOut(function(){
tpl.remove();
});
});
// Automatically upload the file once it is added to the queue
var jqXHR = data.submit();
},
progress: function(e, data){
// Calculate the completion percentage of the upload
var progress = parseInt(data.loaded / data.total * 100, 10);
// Update the hidden input field and trigger a change
// so that the jQuery knob plugin knows to update the dial
data.context.find('input').val(progress).change();
if(progress == 100){
data.context.removeClass('working');
}
}
});
//Helper function for calculation of progress
function formatFileSize(bytes) {
if (typeof bytes !== 'number') {
return '';
}
if (bytes >= 1000000000) {
return (bytes / 1000000000).toFixed(2) + ' GB';
}
if (bytes >= 1000000) {
return (bytes / 1000000).toFixed(2) + ' MB';
}
return (bytes / 1000).toFixed(2) + ' KB';
}
这里是处理数据的 PHP 代码示例:
And here is the PHP code sample to process the data:
if($_POST) {
$allowed = array('jpg', 'jpeg');
if(isset($_FILES['uploadctl']) && $_FILES['uploadctl']['error'] == 0){
$extension = pathinfo($_FILES['uploadctl']['name'], PATHINFO_EXTENSION);
if(!in_array(strtolower($extension), $allowed)){
echo '{"status":"error"}';
exit;
}
if(move_uploaded_file($_FILES['uploadctl']['tmp_name'], "/yourpath/." . $extension)){
echo '{"status":"success"}';
exit;
}
echo '{"status":"error"}';
}
exit();
}
以上代码可以添加到任何现有表单中.添加图像后,该程序会自动上传图像.此功能可以更改,您可以在提交现有表单的同时提交图像.
The above code can be added to any existing form. This program automatically uploads images, once they are added. This functionality can be changed and you can submit the image, while you are submitting your existing form.
用实际代码更新了我的答案.全部归功于代码的原始作者.
Updated my answer with actual code. All credits to original author of the code.
来源:http://tutorialzine.com/2013/05/mini-ajax-file-upload-form/
这篇关于有人可以解释如何实现 jQuery 文件上传插件吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!