我想用 jQuery 异步上传文件。
$(document).ready(function () { $(“#uploadbutton”).click(function () { var filename = $(“#file”).val(); $.ajax({ type: “POST” , url: “addFile.do”, enctype: ‘multipart/form-data’, data: { file: filename }, success: function () { alert("Data Uploaded: "); } }); }); } ); 文件
我只获取文件名,而不是上传文件。我能做些什么来解决这个问题?
huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。
使用 HTML5,您可以使用 Ajax 和 jQuery 进行文件上传。不仅如此,您还可以进行文件验证(名称、大小和 MIME 类型)或使用 HTML5 进度标记(或 div)处理进度事件。最近我不得不制作一个文件上传器,但我不想使用 Flash 也不想使用 iframe 或插件,经过一番研究,我想出了解决方案。
的HTML:
首先,您可以根据需要进行一些验证。例如,在文件的 .on(‘change’) 事件中:
$(':file').on('change', function () {
var file = this.files[0];
if (file.size > 1024) {
alert('max upload size is 1k');
}
// Also see .name, .type
});
现在点击按钮提交 $.ajax():
$(':button').on('click', function () {
$.ajax({
// Your server script to process the upload
url: 'upload.php',
type: 'POST',
// Form data
data: new FormData($('form')[0]),
// Tell jQuery not to process data or worry about content-type
// You *must* include these options!
cache: false,
contentType: false,
processData: false,
// Custom XMLHttpRequest
xhr: function () {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
// For handling the progress of the upload
myXhr.upload.addEventListener('progress', function (e) {
if (e.lengthComputable) {
$('progress').attr({
value: e.loaded,
max: e.total,
});
}
}, false);
}
return myXhr;
}
});
});
如您所见,使用 HTML5(和一些研究)文件上传不仅变得可能而且超级容易。尝试使用 Google Chrome,因为示例的某些 HTML5 组件并非在所有浏览器中都可用。
我有文件部分工作......但你可以在其中包含文本字段吗?这似乎与 var formData = new FormData($('form')[0]); 或 serialize() 无关?
然后我可以在upload.php 中使用$_FILES 吗?
这应该可以在 Internet Explorer 中使用,但只能在版本 10 中使用。(caniuse.com/xhr2)
嗨,我很欣赏 PHP 是您选择的语言...但我想知道您是否知道这是否也适用于 ASP.NET MVC?我是一名 .NET 开发人员,我尝试利用您的简单示例进行一些 AJAX 文件上传,但服务器端我没有获得通过 AJAX 发布的文件。我正在使用最新的 Chrome。
FormData 在这里施展了所有魔法。请务必查看这些文档——它涵盖了您关于多个文件和字段的所有问题。
huntsbot.com – 高效赚钱,自由工作
2019 年更新:这仍然取决于您的人口统计使用的浏览器。
了解“新”HTML5 file API 的重要一点是它wasn’t supported until IE 10。如果您瞄准的特定市场对旧版本 Windows 的倾向高于平均水平,您可能无法访问它。
截至 2017 年,大约 5% 的浏览器是 IE 6、7、8 或 9 之一。如果你进入一家大公司(例如,这是一个 B2B 工具或你提供的培训工具),这个数字可能会飙升。 2016 年,我与一家公司打交道,他们 60% 以上的机器都使用 IE8。
到本次编辑时是 2019 年,距离我最初的回答已经过去了将近 11 年。 IE9 及更低版本的全球使用率在 1% 左右,但仍有较高使用率的集群。
从中获得的重要收获(无论功能如何)是,检查您的用户使用的浏览器。如果你不这样做,你将快速而痛苦地学到为什么“为我工作”在交付给客户时不够好。 caniuse 是一个有用的工具,但请注意他们从何处获取人口统计数据。它们可能与您的不一致。这从来没有比企业环境更真实。
我在 2008 年的回答如下。
但是,有一些可行的非 JS 文件上传方法。您可以在页面上创建一个 iframe(使用 CSS 隐藏),然后将表单定位到该 iframe。主页不需要移动。
这是一个“真实”的帖子,所以它不是完全互动的。如果您需要状态,则需要在服务器端进行处理。这取决于您的服务器。 ASP.NET 有更好的机制。 PHP plain 失败,但您可以使用 Perl 或 Apache 修改来绕过它。
如果您需要上传多个文件,最好一次上传一个文件(以克服最大文件上传限制)。将第一个表单发布到 iframe,使用上述方法监视其进度,完成后,将第二个表单发布到 iframe,依此类推。
或者使用 Java/Flash 解决方案。他们可以更灵活地处理他们的帖子…
作为记录,如果浏览器支持 File API,现在可以进行纯 AJAX 文件上传 - developer.mozilla.org/en/using_files_from_web_applications
这是一个相当古老的答案,但它有点误导.. IE 早在 IE7 就本机支持 XHR,并且早在 IE5 就通过 ActiveX 支持它。 w3schools.com/ajax/ajax_xmlhttprequest_create.asp。执行此操作的实际方法当然是针对 Flash(冲击波)组件,或推出 Flash/ActiveX (Silverlight) 控件。如果您可以通过 javascript 发起请求并处理响应,那么它就是 ajax。尽管如此,ajax 是 xhr 的同义词,但它本身并没有描述传递/交换有效负载的下划线机制/组件。
@BrettCaswell 我并不是说 AJAX/XHR 是不可能的,只是不可能在旧的——但永远存在的——IE 版本上发布文件。那是并且仍然是完全正确的。
HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com
为此,我建议使用 Fine Uploader 插件。您的 JavaScript 代码将是:
$(document).ready(function() {
$("#uploadbutton").jsupload({
action: "addFile.do",
onComplete: function(response){
alert( "server response: " + response);
}
});
});
“这个插件在 GNU GPL 2 或更高版本以及 GNU LGPL 2 或更高版本下开源。”因此,只要您不分发副本或修改版本,您就不必打开您的项目。
如果有人试图走这条路,FineUploader 已于 2018 年停产。github.com/FineUploader/fine-uploader/issues/2073
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求
注意:此答案已过时,现在可以使用 XHR 上传文件。
您无法使用 XMLHttpRequest (Ajax) 上传文件。您可以使用 iframe 或 Flash 模拟效果。优秀的 jQuery Form Plugin 通过 iframe 发布您的文件以获得效果。
小备注:在最新版本的 chrome 和 firefox 中是可能的,stackoverflow.com/questions/4856917/…
打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!
为未来的读者总结。
异步文件上传
使用 HTML5
如果支持 FormData 和 File API(两种 HTML5 功能),您可以使用 $.ajax() 方法使用 jQuery 上传文件。
您也可以发送文件 without FormData,但无论哪种方式,文件 API 都必须存在以处理文件,以便它们可以通过 XMLHttpRequest (Ajax) 发送。
$.ajax({
url: 'file/destination.html',
type: 'POST',
data: new FormData($('#formWithFiles')[0]), // The form with the file inputs.
processData: false,
contentType: false // Using FormData, no need to process data.
}).done(function(){
console.log("Success: Files sent!");
}).fail(function(){
console.log("An error occurred, the files couldn't be sent!");
});
如需快速、纯 JavaScript(无 jQuery)示例,请参阅“Sending files using a FormData object”。
倒退
当不支持 HTML5(无 File API)时,唯一的其他纯 JavaScript 解决方案(无 Flash 或任何其他浏览器插件)是隐藏 iframe 技术,它允许在不使用 XMLHttpRequest 对象的情况下模拟异步请求。
它包括使用文件输入将 iframe 设置为表单的目标。当用户提交请求并上传文件时,响应显示在 iframe 内,而不是重新呈现主页。隐藏 iframe 使整个过程对用户透明并模拟异步请求。
如果处理得当,它几乎可以在任何浏览器上运行,但它有一些关于如何从 iframe 获取响应的警告。
在这种情况下,您可能更喜欢使用像 Bifröst 这样的包装插件,它使用 iframe 技术,但还提供了一个 jQuery Ajax transport,允许仅使用 $.ajax()send files像这样的方法:
$.ajax({
url: 'file/destination.html',
type: 'POST',
// Set the transport to use (iframe means to use Bifröst)
// and the expected data type (json in this case).
dataType: 'iframe json',
fileInputs: $('input[type="file"]'), // The file inputs containing the files to send.
data: { msg: 'Some extra data you might need.'}
}).done(function(){
console.log("Success: Files sent!");
}).fail(function(){
console.log("An error occurred, the files couldn't be sent!");
});
插件
Bifröst 只是一个小型包装器,它为 jQuery 的 ajax 方法添加了回退支持,但许多上述插件(如 jQuery Form Plugin 或 jQuery File Upload)包含从 HTML5 到不同回退的整个堆栈以及一些有用的功能来简化流程。根据您的需要和要求,您可能需要考虑裸实现或其中任何一个插件。
Bifrost 甚至不附加 POST 数据……强烈不推荐这个,粗略的插件,浪费时间。
huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。
此 AJAX file upload jQuery plugin 上传文件,并将响应传递给回调,仅此而已。
它不依赖于特定的 HTML,只需给它一个
它不需要您的服务器以任何特定方式响应
使用多少文件或它们在页面上的位置都没有关系
– 少用 –
$('#one-specific-file').ajaxfileupload({
'action': '/upload.php'
});
——或多于——
$('input[type="file"]').ajaxfileupload({
'action': '/upload.php',
'params': {
'extra': 'info'
},
'onComplete': function(response) {
console.log('custom handler for file:');
alert(JSON.stringify(response));
},
'onStart': function() {
if(weWantedTo) return false; // cancels upload
},
'onCancel': function() {
console.log('no file selected');
}
});
huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。
我一直在使用下面的脚本来上传恰好可以正常工作的图像。
HTML
JavaScript
jQuery('document').ready(function(){
var input = document.getElementById("file");
var formdata = false;
if (window.FormData) {
formdata = new FormData();
}
input.addEventListener("change", function (evt) {
var i = 0, len = this.files.length, img, reader, file;
for ( ; i < len; i++ ) {
file = this.files[i];
if (!!file.type.match(/image.*/)) {
if ( window.FileReader ) {
reader = new FileReader();
reader.onloadend = function (e) {
//showUploadedItem(e.target.result, file.fileName);
};
reader.readAsDataURL(file);
}
if (formdata) {
formdata.append("image", file);
formdata.append("extra",'extra-data');
}
if (formdata) {
jQuery('div#response').html('');
jQuery.ajax({
url: "upload.php",
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (res) {
jQuery('div#response').html("Successfully uploaded");
}
});
}
}
else
{
alert('Not a vaild image!');
}
}
}, false);
});
解释
我使用响应 div 来显示上传动画和上传完成后的响应。
最好的部分是您可以发送额外的数据,例如 ids &等使用此脚本时的文件。我在脚本中提到了它extra-data。
在 PHP 级别,这将像正常的文件上传一样工作。额外数据可以作为 $_POST 数据检索。
在这里,您没有使用插件和东西。您可以根据需要更改代码。您不是在这里盲目编码。这是任何 jQuery 文件上传的核心功能。实际上是Javascript。
huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。
你可以很容易地在 vanilla JavaScript 中做到这一点。这是我当前项目的一个片段:
var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(e) {
var percent = (e.position/ e.totalSize);
// Render a pretty progress bar
};
xhr.onreadystatechange = function(e) {
if(this.readyState === 4) {
// Handle file upload complete
}
};
xhr.open('POST', '/upload', true);
xhr.setRequestHeader('X-FileName',file.name); // Pass the filename along
xhr.send(file);
huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。
您可以简单地使用 jQuery .ajax() 上传。
HTML:
File:
CSS
.progress { display: none; }
Javascript:
$(document).ready(function(ev) {
$("#upload-form").on('submit', (function(ev) {
ev.preventDefault();
$.ajax({
xhr: function() {
var progress = $('.progress'),
xhr = $.ajaxSettings.xhr();
progress.show();
xhr.upload.onprogress = function(ev) {
if (ev.lengthComputable) {
var percentComplete = parseInt((ev.loaded / ev.total) * 100);
progress.val(percentComplete);
if (percentComplete === 100) {
progress.hide().val(0);
}
}
};
return xhr;
},
url: 'upload.php',
type: 'POST',
data: new FormData(this),
contentType: false,
cache: false,
processData: false,
success: function(data, status, xhr) {
// ...
},
error: function(xhr, status, error) {
// ...
}
});
}));
});
进展很好;-)
HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com
我过去做过的最简单和最可靠的方法是简单地将隐藏的 iFrame 标记与您的表单一起定位 - 然后它将在 iframe 内提交而无需重新加载页面。
也就是说,如果您不想使用插件、JavaScript 或 HTML 以外的任何其他形式的“魔法”。当然,你可以将它与 JavaScript 或你有什么结合起来…
您还可以读取 iframe onLoad 的内容以了解服务器错误或成功响应,然后将其输出给用户。
Chrome、iFrame 和 onLoad
-注意-如果您对如何在上传/下载时设置 UI 阻止程序感兴趣,您只需要继续阅读
目前,Chrome 在用于传输文件时不会触发 iframe 的 onLoad 事件。 Firefox、IE 和 Edge 都会触发文件传输的 onload 事件。
我发现适用于 Chrome 的唯一解决方案是使用 cookie。
基本上在开始上传/下载时做到这一点:
[Client Side] 启动一个间隔来寻找cookie的存在
[服务器端] 对文件数据做任何你想做的事
[服务器端] 为客户端间隔设置 cookie
[客户端] Interval 看到 cookie 并像 onLoad 事件一样使用它。例如,您可以启动 UI 阻止程序,然后 onLoad(或在制作 cookie 时)删除 UI 阻止程序。
为此使用 cookie 很难看,但它确实有效。
我在下载时为 Chrome 制作了一个 jQuery 插件来处理这个问题,你可以在这里找到
https://github.com/ArtisticPhoenix/jQuery-Plugins/blob/master/iDownloader.js
同样的基本原则也适用于上传。
使用下载器(显然包括 JS)
$('body').iDownloader({
"onComplete" : function(){
$('#uiBlocker').css('display', 'none'); //hide ui blocker on complete
}
});
$('somebuttion').click( function(){
$('#uiBlocker').css('display', 'block'); //block the UI
$('body').iDownloader('download', 'htttp://example.com/location/of/download');
});
在服务器端,就在传输文件数据之前,创建 cookie
setcookie('iDownloader', true, time() + 30, "/");
插件将看到 cookie,然后触发 onComplete 回调。
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求
I’ve written this up in a Rails environment。如果你使用轻量级的 jQuery-form 插件,它只有大约五行 JavaScript。
挑战在于让 AJAX 上传工作,因为标准 remote_form_for 不理解多部分表单提交。它不会发送 Rails 通过 AJAX 请求返回的文件数据。
这就是 jQuery-form 插件发挥作用的地方。
这是它的 Rails 代码:
<% remote_form_for(:image_form,
:url => { :controller => "blogs", :action => :create_asset },
:html => { :method => :post,
:id => 'uploadForm', :multipart => true })
do |f| %>
Upload a file: <%= f.file_field :uploaded_data %>
<% end %>
这是相关的 JavaScript:
$('#uploadForm input').change(function(){
$(this).parent().ajaxSubmit({
beforeSubmit: function(a,f,o) {
o.dataType = 'json';
},
complete: function(XMLHttpRequest, textStatus) {
// XMLHttpRequest.responseText will contain the URL of the uploaded image.
// Put it in an image element you create, or do with it what you will.
// For example, if you have an image elemtn with id "my_image", then
// $('#my_image').attr('src', XMLHttpRequest.responseText);
// Will set that image tag to display the uploaded image.
},
});
});
这是 Rails 控制器动作,非常普通:
@image = Image.new(params[:image_form])
@image.save
render :text => @image.public_filename
在过去的几周里,我一直在用 Bloggity 使用它,它的工作就像一个冠军。
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求