javascript表單處理
如何異步上傳文件? (20)
2017年更新:它仍然取決於您的人口統計使用的瀏覽器。
使用“新”HTML5 file
API需要了解的重要事項是IE 10之前不支持 。 如果您所針對的特定市場對舊版Windows的傾向高於平均水平,則可能無法訪問它。
進入2017年,大約5%的瀏覽器是IE 6,7,8或9中的一個。如果你進入一家大公司(例如,這是一個B2B工具,或者你正在提供培訓的東西),那麼這個數字可能會火上澆油。 就在幾個月前 - 在2016年 - 我在超過60%的機器上使用IE8處理了一家公司。
因此,在您執行任何操作之前: 檢查用戶使用的瀏覽器 。 如果你不這樣做,你將學到一個快速而痛苦的教訓,為什麼“為我工作”對於客戶的交付是不夠的。
我的答案是從2008年開始的。
但是,有一些可行的非JS文件上傳方法。 您可以在頁面上創建一個iframe(使用CSS隱藏),然後將表單定位到該iframe。 主頁不需要移動。
這是一個“真正的”帖子,所以它不是完全互動的。 如果您需要狀態,則需要服務器端進行處理。 這根據您的服務器而有很大差異。 ASP.NET具有更好的機制。 PHP plain失敗,但您可以使用Perl或Apache修改來繞過它。
如果您需要多個文件上傳,最好一次執行一個文件(以克服最大文件上載限制)。 將第一個表單發佈到iframe,使用上面的內容監控其進度,完成後,將第二個表單發佈到iframe,依此類推。
或者使用Java / Flash解決方案。 他們對帖子的處理方式更加靈活......
我想用jQuery異步上傳一個文件。 這是我的HTML:
<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>
在這裡我的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: ");
}
});
});
});
我只獲取文件名,而不是上傳文件。 我該怎麼做才能解決這個問題?
當前解決方案
我正在使用jQuery Form Plugin上傳文件。
jQuery Uploadify是我之前用來上傳文件的另一個好插件。 JavaScript代碼與以下內容一樣簡單:代碼。 但是,新版本在Internet Explorer中不起作用。
$('#file_upload').uploadify({
'swf': '/public/js/uploadify.swf',
'uploader': '/Upload.ashx?formGuid=' + $('#formGuid').val(),
'cancelImg': '/public/images/uploadify-cancel.png',
'multi': true,
'onQueueComplete': function (queueData) {
// ...
},
'onUploadStart': function (file) {
// ...
}
});
我已經做了很多搜索,我已經找到了另一個沒有任何插件上傳文件的解決方案,只有ajax。 解決方案如下:
$(document).ready(function () {
$('#btn_Upload').live('click', AjaxFileUpload);
});
function AjaxFileUpload() {
var fileInput = document.getElementById("#Uploader");
var file = fileInput.files[0];
var fd = new FormData();
fd.append("files", file);
var xhr = new XMLHttpRequest();
xhr.open("POST", 'Uploader.ashx');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
alert('success');
}
else if (uploadResult == 'success')
alert('error');
};
xhr.send(fd);
}
你可以很容易地在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);
使用HTML5您可以使用Ajax和jQuery進行文件上傳。 不僅如此,您還可以使用HTML5進度標記(或div)進行文件驗證(名稱,大小和MIME類型)或處理進度事件。 最近我不得不製作文件上傳器,但我不想使用Flash也不想使用Iframe或插件,經過一些研究後我想出了解決方案。
HTML:
<form enctype="multipart/form-data">
<input name="file" type="file" />
<input type="button" value="Upload" />
</form>
<progress></progress>
首先,如果需要,您可以進行一些驗證。 例如,在文件的onChange事件中:
$(':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(以及一些研究)文件上傳不僅可以實現,而且非常簡單。 嘗試使用谷歌瀏覽器,因為每個瀏覽器都沒有這些示例的HTML5組件。
您可以使用
$(function() {
$("#file_upload_1").uploadify({
height : 30,
swf : '/uploadify/uploadify.swf',
uploader : '/uploadify/uploadify.php',
width : 120
});
});
我一直在使用下面的腳本來上傳恰好工作的圖像。
HTML
<input id="file" type="file" name="file"/>
<div id="response"></div>
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('<br /><img src="ajax-loader.gif"/>');
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。
我找到的解決方案是讓<form>
目標成為隱藏的iFrame。 然後,iFrame可以運行JS以向用戶顯示它已完成(在頁面加載時)。
我遇到了一些非常強大的基於jQuery的文件上傳庫。 看看這些:
- Plupload
- jQuery文件上傳
- docs: https : //github.com/blueimp/jQuery-File-Upload
- fineuploader.com
有關jQuery的文件上傳有各種現成的插件。
做這種上傳黑客並不是一種愉快的體驗,因此人們喜歡使用現成的解決方案。
這裡有幾個:
您可以在NPM上搜索更多項目(使用“jquery-plugin”作為關鍵字)或在Github上搜索。
注意:此答案已過時,現在可以使用XHR上傳文件。
您無法使用XMLHttpRequest (Ajax)上傳文件。 您可以使用iframe或Flash模擬效果。 優秀的jQuery表單插件 ,通過iframe發布您的文件以獲得效果。
簡單的Ajax Uploader是另一種選擇:
https://github.com/LPology/Simple-Ajax-Uploader
- 跨瀏覽器 - 適用於IE7 +,Firefox,Chrome,Safari,Opera
- 支持多個並發上傳 - 即使在非HTML5瀏覽器中也是如此
- 沒有閃存或外部CSS - 只有一個5Kb的Javascript文件
- 完全跨瀏覽器進度條的可選內置支持(使用PHP的APC擴展)
- 靈活且高度可定制 - 使用任何元素作為上傳按鈕,設置您自己的進度指示器的樣式
- 無需表單,只需提供一個用作上傳按鈕的元素即可
- 麻省理工學院許可證 - 免費用於商業項目
用法示例:
var uploader = new ss.SimpleUpload({
button: $('#uploadBtn'), // upload button
url: '/uploadhandler', // URL of server-side upload handler
name: 'userfile', // parameter name of the uploaded file
onSubmit: function() {
this.setProgressBar( $('#progressBar') ); // designate elem as our progress bar
},
onComplete: function(file, response) {
// do whatever after upload is finished
}
});
要使用Jquery異步上傳文件,請使用以下步驟:
步驟1在你的項目中打開Nuget管理器並添加包(jquery fileupload(只需要在搜索框中編寫它就會出現並安裝它。)URL:https://github.com/blueimp/jQuery-File-上傳
步驟2在HTML文件中添加以下腳本,這些腳本已通過運行上面的包添加到項目中:
jquery.ui.widget.js
jquery.iframe-transport.js
jquery.fileupload.js
步驟3按以下代碼編寫文件上傳控件:
<input id="upload" name="upload" type="file" />
第4步將js方法寫為uploadFile,如下所示:
function uploadFile(element) {
$(element).fileupload({
dataType: 'json',
url: '../DocumentUpload/upload',
autoUpload: true,
add: function (e, data) {
// write code for implementing, while selecting a file.
// data represents the file data.
//below code triggers the action in mvc controller
data.formData =
{
files: data.files[0]
};
data.submit();
},
done: function (e, data) {
// after file uploaded
},
progress: function (e, data) {
// progress
},
fail: function (e, data) {
//fail operation
},
stop: function () {
code for cancel operation
}
});
};
步驟5在ready函數調用元素文件上傳中,按以下方式啟動進程:
$(document).ready(function()
{
uploadFile($('#upload'));
});
步驟6按以下方式編寫MVC控制器和操作:
public class DocumentUploadController : Controller
{
[System.Web.Mvc.HttpPost]
public JsonResult upload(ICollection<HttpPostedFileBase> files)
{
bool result = false;
if (files != null || files.Count > 0)
{
try
{
foreach (HttpPostedFileBase file in files)
{
if (file.ContentLength == 0)
throw new Exception("Zero length file!");
else
//code for saving a file
}
}
catch (Exception)
{
result = false;
}
}
return new JsonResult()
{
Data=result
};
}
}
這是我的解決方案。
<form enctype="multipart/form-data">
<div class="form-group">
<label class="control-label col-md-2" for="apta_Description">Description</label>
<div class="col-md-10">
<input class="form-control text-box single-line" id="apta_Description" name="apta_Description" type="text" value="">
</div>
</div>
<input name="file" type="file" />
<input type="button" value="Upload" />
</form>
和js
<script>
$(':button').click(function () {
var formData = new FormData($('form')[0]);
$.ajax({
url: '@Url.Action("Save", "Home")',
type: 'POST',
success: completeHandler,
data: formData,
cache: false,
contentType: false,
processData: false
});
});
function completeHandler() {
alert(":)");
}
</script>
調節器
[HttpPost]
public ActionResult Save(string apta_Description, HttpPostedFileBase file)
{
return Json(":)");
}
這裡只是如何上傳文件的另一種解決方案( 沒有任何插件 )
使用簡單的Javascripts和AJAX (帶進度條)
HTML部分
<form id="upload_form" enctype="multipart/form-data" method="post">
<input type="file" name="file1" id="file1"><br>
<input type="button" value="Upload File" onclick="uploadFile()">
<progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
<h3 id="status"></h3>
<p id="loaded_n_total"></p>
</form>
JS部分
function _(el){
return document.getElementById(el);
}
function uploadFile(){
var file = _("file1").files[0];
// alert(file.name+" | "+file.size+" | "+file.type);
var formdata = new FormData();
formdata.append("file1", file);
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "file_upload_parser.php");
ajax.send(formdata);
}
function progressHandler(event){
_("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total;
var percent = (event.loaded / event.total) * 100;
_("progressBar").value = Math.round(percent);
_("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
}
function completeHandler(event){
_("status").innerHTML = event.target.responseText;
_("progressBar").value = 0;
}
function errorHandler(event){
_("status").innerHTML = "Upload Failed";
}
function abortHandler(event){
_("status").innerHTML = "Upload Aborted";
}
PHP部分
<?php
$fileName = $_FILES["file1"]["name"]; // The file name
$fileTmpLoc = $_FILES["file1"]["tmp_name"]; // File in the PHP tmp folder
$fileType = $_FILES["file1"]["type"]; // The type of file it is
$fileSize = $_FILES["file1"]["size"]; // File size in bytes
$fileErrorMsg = $_FILES["file1"]["error"]; // 0 for false... and 1 for true
if (!$fileTmpLoc) { // if file not chosen
echo "ERROR: Please browse for a file before clicking the upload button.";
exit();
}
if(move_uploaded_file($fileTmpLoc, "test_uploads/$fileName")){ // assuming the directory name 'test_uploads'
echo "$fileName upload is complete";
} else {
echo "move_uploaded_file function failed";
}
?>
你可以使用JavaScript或jQuery進行異步多文件上傳,而不使用任何插件。您還可以在進度控件中顯示文件上載的實時進度。我遇到了兩個不錯的鏈接 -
服務器端語言是C#,但您可以進行一些修改,使其與PHP等其他語言一起使用。
文件上載ASP.NET Core MVC:
在html中的View create file upload control中:
[HttpPost]
public async Task<IActionResult> Add(IFormFile[] mediaUpload)
{
//looping through all the files
foreach (IFormFile file in mediaUpload)
{
//saving the files
string path = Path.Combine(hostingEnvironment.WebRootPath, "some-folder-path");
using (var stream = new FileStream(path, FileMode.Create))
{
await file.CopyToAsync(stream);
}
}
}
現在在控制器中創建動作方法:
private IHostingEnvironment hostingEnvironment;
public MediaController(IHostingEnvironment environment)
{
hostingEnvironment = environment;
}
hostingEnvironment變量的類型為IHostingEnvironment,可以使用依賴注入將其註入控制器,如:
$('#fileupload').fileupload({
add: function (e, data) {
var that = this;
$.getJSON('/example/url', function (result) {
data.formData = result; // e.g. {id: 123}
$.blueimp.fileupload.prototype
.options.add.call(that, e, data);
});
}
});
使用HTML5和JavaScript,上傳異步很容易,我創建上傳邏輯和你的html,這不是完全工作,因為它需要api,但演示它是如何工作的,如果你/upload
從你的網站的根調用端點,這段代碼應該適合你:
const asyncFileUpload = () => {
const fileInput = document.getElementById("file");
const file = fileInput.files[0];
const uri = "/upload";
const xhr = new XMLHttpRequest();
xhr.upload.onprogress = e => {
const percentage = e.loaded / e.total;
console.log(percentage);
};
xhr.onreadystatechange = e => {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log("file uploaded");
}
};
xhr.open("POST", uri, true);
xhr.setRequestHeader("X-FileName", file.name);
xhr.send(file);
}
<form>
<span>File</span>
<input type="file" id="file" name="file" size="10" />
<input onclick="asyncFileUpload()" id="upload" type="button" value="Upload" />
</form>
還有一些關於XMLHttpReques的更多信息:
XMLHttpRequest對象
所有現代瀏覽器都支持XMLHttpRequest對象。XMLHttpRequest對象可用於在後台與Web服務器交換數據。這意味著可以更新網頁的各個部分,而無需重新加載整個頁面。
創建XMLHttpRequest對象
所有現代瀏覽器(Chrome,Firefox,IE7 +,Edge,Safari,Opera)都有一個內置的XMLHttpRequest對象。
創建XMLHttpRequest對象的語法:
variable = new XMLHttpRequest();
跨域訪問
出於安全原因,現代瀏覽器不允許跨域訪問。
這意味著網頁和它嘗試加載的XML文件必須位於同一台服務器上。
W3Schools上的示例都是位於W3Schools域的所有開放XML文件。
如果要在自己的某個網頁上使用上述示例,則加載的XML文件必須位於您自己的服務器上。
欲了解更多詳情,您可以繼續閱讀here ...
您可以here看到已解決的解決方案,其中包含一個工作演示,允許您預覽表單文件並將其提交給服務器。對於您的情況,您需要使用Ajax來方便將文件上載到服務器:
<from action="" id="formContent" method="post" enctype="multipart/form-data">
<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>
</form>
提交的數據是一個表格數據。在您的jQuery上,使用表單提交功能而不是單擊按鈕來提交表單文件,如下所示。
$(document).ready(function () {
$("#formContent").submit(function(e){
e.preventDefault();
var formdata = new FormData(this);
$.ajax({
url: "ajax_upload_image.php",
type: "POST",
data: formdata,
mimeTypes:"multipart/form-data",
contentType: false,
cache: false,
processData: false,
success: function(){
alert("successfully submitted");
});
});
});
您可以使用XMLHttpRequest(沒有flash和iframe依賴)在進行異步上載時傳遞其他參數和文件名。使用FormData附加附加參數值並發送上載請求。
function uploadButtonCLicked(){
var input = document.querySelector('input[type="file"]')
fetch('/url', {
method: 'POST',
body: input.files[0]
}).then(res => res.json()) // you can do something with response
.catch(error => console.error('Error:', error))
.then(response => console.log('Success:', response));
}
此外,Syncfusion JavaScript UI文件上載僅使用事件參數為此方案提供解決方案。你可以找到的文檔在這裡和有關此控件的詳細信息在這裡輸入鏈接的描述在這裡
示例:如果您使用jQuery,則可以輕鬆上傳文件。這是一個小而強大的jQuery插件,http://jquery.malsup.com/form/。
例
var $bar = $('.ProgressBar');
$('.Form').ajaxForm({
dataType: 'json',
beforeSend: function(xhr) {
var percentVal = '0%';
$bar.width(percentVal);
},
uploadProgress: function(event, position, total, percentComplete) {
var percentVal = percentComplete + '%';
$bar.width(percentVal)
},
success: function(response) {
// Response
}
});
我希望它會有所幫助
請在此處異步處理文件的上傳過程:https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
來自鏈接的示例
<?php
if (isset($_FILES['myFile'])) {
// Example:
move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile']['name']);
exit;
}
?><!DOCTYPE html>
<html>
<head>
<title>dnd binary upload</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript">
function sendFile(file) {
var uri = "/index.php";
var xhr = new XMLHttpRequest();
var fd = new FormData();
xhr.open("POST", uri, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
// Handle response.
alert(xhr.responseText); // handle response.
}
};
fd.append('myFile', file);
// Initiate a multipart/form-data upload
xhr.send(fd);
}
window.onload = function() {
var dropzone = document.getElementById("dropzone");
dropzone.ondragover = dropzone.ondragenter = function(event) {
event.stopPropagation();
event.preventDefault();
}
dropzone.ondrop = function(event) {
event.stopPropagation();
event.preventDefault();
var filesArray = event.dataTransfer.files;
for (var i=0; i<filesArray.length; i++) {
sendFile(filesArray[i]);
}
}
}
</script>
</head>
<body>
<div>
<div id="dropzone" style="margin:30px; width:500px; height:300px; border:1px dotted grey;">Drag & drop your file here...</div>
</div>
</body>
</html>