有人可以解释如何实现 jQuery File Upload 插件吗?
Posted
技术标签:
【中文标题】有人可以解释如何实现 jQuery File Upload 插件吗?【英文标题】:Can someone explain how to implement the jQuery File Upload plugin? 【发布时间】:2013-07-29 20:55:22 【问题描述】:编辑(2019 年 10 月):
6 年后,jQuery File Upload 显然仍然让人们发疯。如果您在此处的答案中找不到一点安慰,请尝试search of NPM 以获得现代替代方案。我保证,这不值得麻烦。
我在之前的编辑中推荐了 Uploadify,但正如评论者指出的那样,他们似乎不再提供免费版本。无论如何,Uploadify 是 所以 2013 年。
编辑:
这似乎仍在吸引流量,所以我将解释我最终做了什么。我最终按照已接受答案中的教程使插件正常工作。背景
我正在尝试使用 blueimp 的 jQuery File Upload 来允许用户上传文件。 开箱即可完美运行,按照设置说明进行操作。但要在我的网站上实际使用它,我希望能够做几件事:
在我的任何现有页面中包含上传者 更改上传文件的目录插件的所有文件都位于根目录下的文件夹中。
我试过了……
将演示页面移至根目录并更新必要脚本的路径 按照建议 here 更改 UploadHandler.php 文件中的“upload_dir”和“upload_url”选项。 在演示 javascript 的第二行中更改 URL在所有情况下,预览都会显示,进度条会运行,但文件上传失败,我在控制台中收到此错误:Uncaught TypeError: Cannot read property 'files' of undefined
。我不明白插件的所有部分是如何工作的,这使得调试变得困难。
代码
演示页面中的javascript:
$(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');
);
我对缺乏文档感到惊讶;似乎改变应该是一件简单的事情。如果有人能解释如何做到这一点,我将不胜感激。
【问题讨论】:
好的问题格式。很高兴看到组织。 在错误行之前的控制台中打印'e'和'data',值是什么? Uploadify 是 MIT 许可证,例如它是完全免费的。但是,来自同一 dev/website 的上传五个是 5-100 美元,具体取决于使用情况 两年来,jQuery-File-Upload 文档并没有变得更好。啊。 @MartinJH 可能在某个时候进行了uploadify,但目前只有一个-付费uploadiFive 版本。而且也没有演示;这只是一个视频。形式不佳。 【参考方案1】:几天前我一直在寻找类似的功能,并在 tutorialzine 上发现了一个很好的教程。这是一个工作示例。完整教程可以在here找到。
保持文件上传对话的简单表格:
<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 代码:
$('#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- data- 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 代码示例:
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();
上面的代码可以添加到任何现有的表单中。一旦添加了图像,该程序会自动上传图像。此功能可以更改,您可以在提交现有表单时提交图像。
用实际代码更新了我的答案。所有功劳归于代码的原作者。
来源: http://tutorialzine.com/2013/05/mini-ajax-file-upload-form/
【讨论】:
你能把那个教程的重要部分复制到这里,所以如果它消失了,你的答案还有用吗? 但注意不要抄袭 注意:对于使用 PHP 代码 sn-p 的任何人,请删除if($_POST)
语句。 POST 应该是空的,文件内容在$_FILES['upfile']['tmp_name']
中发送。希望这可以节省一些时间。
找到另一个c-sharpcorner.com/UploadFile/da55bf/…
谁能建议我运行上述脚本所需的 js/jquery 文件是什么【参考方案2】:
我刚刚花了 2 个小时与 jQuery Upload 作斗争,但由于依赖项的数量而放弃了(我包含了 13 个 JS 文件来获取所有的花里胡哨)。
我进行了更多搜索,发现了一个名为 Dropzone.js 的简洁项目,它没有任何依赖项。
作者还创建了一个bootstrap demo,其灵感来自 jQuery File Upload 插件。
我希望这可以节省其他人一些时间。
【讨论】:
需要注意的重要一点:Dropzone.js 看起来不错,但它只支持 IE10 及更高版本。从 IE6 支持 jQuery 文件上传 ;) jQuery File Upload 是不可能让它工作的......我花了很多时间尝试,因为它有非常好的功能,但在最后一刻我的灵魂只充满了痛苦!多么绝望啊!!!然后我看到了你关于Dropzone.js 的帖子,在 5 分钟内我就按照我想要的方式让它工作了!你救了我…… 感激不尽,我花了将近 12 个小时让jQuery-FIle-Upload 以我想要的方式工作,最后我偶然发现了这个问题。你救了我。 这里是一个数据库驱动的jquery文件上传示例:github.com/CodeHeight/ImageLibrary 我用了 3 天,还是无法自定义他们的代码【参考方案3】:我也为此苦苦挣扎,但一旦我弄清楚 UploadHandler.php 中的路径如何工作,它就可以工作了:upload_dir 和 upload_url 是唯一需要查看的设置才能让它工作。还要检查您的服务器错误日志以获取调试信息。
【讨论】:
【参考方案4】:使用 dropper jquery 插件查看带有图像预览的图像拖放上传器。
HTML
<div class="target" ><img /></div>
JS
$(".target").dropper(
action: "upload.php",
).on("start.dropper", onStart);
function onStart(e, files)
console.log(files[0]);
image_preview(files[0].file).then(function(res)
$('.dropper-dropzone').empty();
//$('.dropper-dropzone').css("background-image",res.data);
$('#imgPreview').remove();
$('.dropper-dropzone').append('<img id="imgPreview"/><span style="display:none">Drag and drop files or click to select</span>');
var widthImg=$('.dropper-dropzone').attr('width');
$('#imgPreview').attr(width:widthImg);
$('#imgPreview').attr(src:res.data);
)
function image_preview(file)
var def = new $.Deferred();
var imgURL = '';
if (file.type.match('image.*'))
//create object url support
var URL = window.URL || window.webkitURL;
if (URL !== undefined)
imgURL = URL.createObjectURL(file);
URL.revokeObjectURL(file);
def.resolve(status: 200, message: 'OK', data:imgURL, error: );
//file reader support
else if(window.File && window.FileReader)
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = function ()
imgURL = reader.result;
def.resolve(status: 200, message: 'OK', data:imgURL, error: );
else
def.reject(status: 1001, message: 'File uploader not supported', data:imgURL, error: );
else
def.reject(status: 1002, message: 'File type not supported', error: );
return def.promise();
$('.dropper-dropzone').mouseenter(function()
$( '.dropper-dropzone>span' ).css("display", "block");
);
$('.dropper-dropzone').mouseleave(function()
$( '.dropper-dropzone>span' ).css("display", "none");
);
CSS
.dropper-dropzone
width:78px;
padding:3px;
height:100px;
position: relative;
.dropper-dropzone>img
width:78px;
height:100px;
margin-top=0;
.dropper-dropzone>span
position: absolute;
right: 10px;
top: 20px;
color:#ccc;
.dropper .dropper-dropzone
padding:3px !important
Demo Jsfiddle
【讨论】:
这是一个非常简单的解决方案。【参考方案5】:这是一个很好的上传文件的Angular插件,而且它是免费的!
angular file upload
【讨论】:
嗨。请不要发布链接作为答案,如果网站下线或链接更改,您的答案将变得毫无用处。相反,请使用网站上的信息来构建您的答案,并将链接仅用作参考。谢谢。【参考方案6】:我在 Rails 上为这个插件苦苦挣扎了一段时间,然后有人将它宝石化,废弃了我创建的所有代码。
虽然看起来你没有在 Rails 中使用它,但是如果有人在使用它,请查看 gem。来源在这里 --> jQueryFileUpload Rails。
更新:
为了让评论者满意,我更新了我的答案。本质上是“use this gem,here is the source code”,如果它消失了,那就走很长的路。
【讨论】:
【参考方案7】:嗨,试试下面的链接,这很容易。我被卡了很长时间,它在几分钟内解决了我的问题。 http://simpleupload.michaelc***.com/#examples
【讨论】:
【参考方案8】:Droply.js 非常适合这个。它很简单,并且预装了一个开箱即用的演示站点。
【讨论】:
【参考方案9】:现在是 2021 年,这是一个非常简单的插件,可以上传任何内容:
https://pqina.nl/filepond/?ref=pqina
添加你的元素:
<input type="file"
class="filepond"
name="filepond"
multiple
data-allow-reorder="true"
data-max-file-size="3MB"
data-max-files="3">
注册任何其他插件:
FilePond.registerPlugin(
FilePondPluginImagePreview,
FilePondPluginImageExifOrientation,
FilePondPluginFileValidateSize,
FilePondPluginImageEdit);
然后在元素中连线:
// Select the file input and use
// create() to turn it into a pond
FilePond.create(
document.querySelector('input'),
// Use Doka.js as image editor
imageEditEditor: Doka.create(
utils: ['crop', 'filter', 'color']
)
);
我将它与额外的 Doka 图像编辑器一起使用,以在 https://www.yoodu.co.uk 上传和转换图像
设置非常简单,运行它的人非常擅长支持。
如你所知,我是个粉丝。
【讨论】:
【参考方案10】:您可以使用uploadify 这是我用过的最好的多上传 jquery 插件。
实现简单,浏览器支持完善。
【讨论】:
你可以使用 HTML 5 版本 :) 如果我没记错的话,html5版本的uploadify不是免费的。它的价格为 5 美元。 uploadify.com/download 但是,这只是 5 美元而不是 500 美元。 请记住,如果您想将uploadify 用于商业用途,您需要购买商业许可证(100 美元)uploadify.com/download/download-uploadifive-commercial 对于任何感兴趣的人,Uploadify = Flash 版本,UploadiFive = HTML5 版本。【参考方案11】:对于UI插件,带有jsp页面和Spring MVC..
示例 html。需要在 form 元素中,并具有 fileupload
的 id 属性 <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
<div class="fileupload-buttonbar">
<div>
<!-- The fileinput-button span is used to style the file input field as button -->
<span class="btn btn-success fileinput-button">
<i class="glyphicon glyphicon-plus"></i>
<span>Add files</span>
<input id="fileuploadInput" type="file" name="files[]" multiple>
</span>
<%-- https://***.com/questions/925334/how-is-the-default-submit-button-on-an-html-form-determined --%>
<button type="button" class="btn btn-primary start">
<i class="glyphicon glyphicon-upload"></i>
<span>Start upload</span>
</button>
<button type="reset" class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel upload</span>
</button>
<!-- The global file processing state -->
<span class="fileupload-process"></span>
</div>
<!-- The global progress state -->
<div class="fileupload-progress fade">
<!-- The global progress bar -->
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar progress-bar-success" style="width:0%;"></div>
</div>
<!-- The extended global progress state -->
<div class="progress-extended"> </div>
</div>
</div>
<!-- The table listing the files available for upload/download -->
<table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>
<link rel="stylesheet" type="text/css" href="$pageContext.request.contextPath/js/jquery-file-upload-9.14.2/css/jquery.fileupload.css">
<link rel="stylesheet" type="text/css" href="$pageContext.request.contextPath/js/jquery-file-upload-9.14.2/css/jquery.fileupload-ui.css">
<script type="text/javascript" src="$pageContext.request.contextPath/js/jquery-file-upload-9.14.2/js/vendor/jquery.ui.widget.js"></script>
<script type="text/javascript" src="$pageContext.request.contextPath/js/jquery-file-upload-9.14.2/js/jquery.iframe-transport.js"></script>
<script type="text/javascript" src="$pageContext.request.contextPath/js/jquery-file-upload-9.14.2/js/jquery.fileupload.js"></script>
<script type="text/javascript" src="$pageContext.request.contextPath/js/jquery-file-upload-9.14.2/js/jquery.fileupload-process.js"></script>
<script type="text/javascript" src="$pageContext.request.contextPath/js/jquery-file-upload-9.14.2/js/jquery.fileupload-validate.js"></script>
<script type="text/javascript" src="$pageContext.request.contextPath/js/jquery-file-upload-9.14.2/js/jquery.fileupload-ui.js"></script>
<script type="text/javascript">
$(document).ready(function ()
var maxFileSizeBytes = $maxFileSizeBytes;
if (maxFileSizeBytes < 0)
//-1 or any negative value means no size limit
//set to undefined
//https://***.com/questions/5795936/how-to-set-a-javascript-var-as-undefined
maxFileSizeBytes = void 0;
//https://github.com/blueimp/jQuery-File-Upload/wiki/Options
//https://***.com/questions/34063348/jquery-file-upload-basic-plus-ui-and-i18n
//https://***.com/questions/11337897/how-to-customize-upload-download-template-of-blueimp-jquery-file-upload
$('#fileupload').fileupload(
url: '$pageContext.request.contextPath/app/uploadResources.do',
fileInput: $('#fileuploadInput'),
acceptFileTypes: /(\.|\/)(jrxml|png|jpe?g)$/i,
maxFileSize: maxFileSizeBytes,
messages:
acceptFileTypes: '$fileTypeNotAllowedText',
maxFileSize: '$fileTooLargeMBText'
,
filesContainer: $('.files'),
uploadTemplateId: null,
downloadTemplateId: null,
uploadTemplate: function (o)
var rows = $();
$.each(o.files, function (index, file)
var row = $('<tr class="template-upload fade">' +
'<td><p class="name"></p>' +
'<strong class="error text-danger"></strong>' +
'</td>' +
'<td><p class="size"></p>' +
'<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">' +
'<div class="progress-bar progress-bar-success" style="width:0%;"></div></div>' +
'</td>' +
'<td>' +
(!index && !o.options.autoUpload ?
'<button class="btn btn-primary start" disabled>' +
'<i class="glyphicon glyphicon-upload"></i> ' +
'<span>$startText</span>' +
'</button>' : '') +
(!index ? '<button class="btn btn-warning cancel">' +
'<i class="glyphicon glyphicon-ban-circle"></i> ' +
'<span>$cancelText</span>' +
'</button>' : '') +
'</td>' +
'</tr>');
row.find('.name').text(file.name);
row.find('.size').text(o.formatFileSize(file.size));
if (file.error)
row.find('.error').text(file.error);
rows = rows.add(row);
);
return rows;
,
downloadTemplate: function (o)
var rows = $();
$.each(o.files, function (index, file)
var row = $('<tr class="template-download fade">' +
'<td><p class="name"></p>' +
(file.error ? '<strong class="error text-danger"></strong>' : '') +
'</td>' +
'<td><span class="size"></span></td>' +
'<td>' +
(file.deleteUrl ? '<button class="btn btn-danger delete">' +
'<i class="glyphicon glyphicon-trash"></i> ' +
'<span>$deleteText</span>' +
'</button>' : '') +
'<button class="btn btn-warning cancel">' +
'<i class="glyphicon glyphicon-ban-circle"></i> ' +
'<span>$clearText</span>' +
'</button>' +
'</td>' +
'</tr>');
row.find('.name').text(file.name);
row.find('.size').text(o.formatFileSize(file.size));
if (file.error)
row.find('.error').text(file.error);
if (file.deleteUrl)
row.find('button.delete')
.attr('data-type', file.deleteType)
.attr('data-url', file.deleteUrl);
rows = rows.add(row);
);
return rows;
);
);
</script>
上传和删除请求处理程序示例
@PostMapping("/app/uploadResources")
public @ResponseBody
Map<String, List<FileUploadResponse>> uploadResources(MultipartHttpServletRequest request,
Locale locale)
//https://github.com/jdmr/fileUpload/blob/master/src/main/java/org/davidmendoza/fileUpload/web/ImageController.java
//https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#using-jquery-file-upload-ui-version-with-a-custom-server-side-upload-handler
Map<String, List<FileUploadResponse>> response = new HashMap<>();
List<FileUploadResponse> fileList = new ArrayList<>();
String deleteUrlBase = request.getContextPath() + "/app/deleteResources.do?filename=";
//http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/multipart/MultipartRequest.html
Iterator<String> itr = request.getFileNames();
while (itr.hasNext())
String htmlParamName = itr.next();
MultipartFile file = request.getFile(htmlParamName);
FileUploadResponse fileDetails = new FileUploadResponse();
String filename = file.getOriginalFilename();
fileDetails.setName(filename);
fileDetails.setSize(file.getSize());
try
String message = saveFile(file);
if (message != null)
String errorMessage = messageSource.getMessage(message, null, locale);
fileDetails.setError(errorMessage);
else
//save successful
String encodedFilename = URLEncoder.encode(filename, "UTF-8");
String deleteUrl = deleteUrlBase + encodedFilename;
fileDetails.setDeleteUrl(deleteUrl);
catch (IOException ex)
logger.error("Error", ex);
fileDetails.setError(ex.getMessage());
fileList.add(fileDetails);
response.put("files", fileList);
return response;
@PostMapping("/app/deleteResources")
public @ResponseBody
Map<String, List<Map<String, Boolean>>> deleteResources(@RequestParam("filename") List<String> filenames)
Map<String, List<Map<String, Boolean>>> response = new HashMap<>();
List<Map<String, Boolean>> fileList = new ArrayList<>();
String templatesPath = Config.getTemplatesPath();
for (String filename : filenames)
Map<String, Boolean> fileDetails = new HashMap<>();
String cleanFilename = ArtUtils.cleanFileName(filename);
String filePath = templatesPath + cleanFilename;
File file = new File(filePath);
boolean deleted = file.delete();
if (deleted)
fileDetails.put(cleanFilename, true);
else
fileDetails.put(cleanFilename, false);
fileList.add(fileDetails);
response.put("files", fileList);
return response;
用于生成所需 json 响应的示例类
public class FileUploadResponse
//https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#using-jquery-file-upload-ui-version-with-a-custom-server-side-upload-handler
private String name;
private long size;
private String error;
private String deleteType = "POST";
private String deleteUrl;
/**
* @return the name
*/
public String getName()
return name;
/**
* @param name the name to set
*/
public void setName(String name)
this.name = name;
/**
* @return the size
*/
public long getSize()
return size;
/**
* @param size the size to set
*/
public void setSize(long size)
this.size = size;
/**
* @return the error
*/
public String getError()
return error;
/**
* @param error the error to set
*/
public void setError(String error)
this.error = error;
/**
* @return the deleteType
*/
public String getDeleteType()
return deleteType;
/**
* @param deleteType the deleteType to set
*/
public void setDeleteType(String deleteType)
this.deleteType = deleteType;
/**
* @return the deleteUrl
*/
public String getDeleteUrl()
return deleteUrl;
/**
* @param deleteUrl the deleteUrl to set
*/
public void setDeleteUrl(String deleteUrl)
this.deleteUrl = deleteUrl;
见https://pitipata.blogspot.co.ke/2017/01/using-jquery-file-upload-ui.html
【讨论】:
以上是关于有人可以解释如何实现 jQuery File Upload 插件吗?的主要内容,如果未能解决你的问题,请参考以下文章