我怎样才能asynchronous上传文件?
我想用jQueryasynchronous上传文件。 这是我的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: "); } }); }); });
而不是被上传的文件,我只获取文件名。 我能做些什么来解决这个问题?
当前解决scheme
我正在使用jQuery表单插件来上传文件。
使用HTML5,您可以使用Ajax和jQuery进行file upload。 不仅如此,您还可以执行文件validation(名称,大小和MIMEtypes)或使用HTML5进度标记(或div)处理进度事件。 最近我不得不做一个file upload,但我不想使用Flash ,iframe或插件,经过一些研究,我想出了解决scheme。
HTML:
<form enctype="multipart/form-data"> <input name="file" type="file" /> <input type="button" value="Upload" /> </form> <progress></progress>
首先,你可以做一些validation,如果你想。 例如,在文件的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的点击:
$(':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(和一些研究)file upload不仅成为可能,而且非常容易。 尝试使用Google Chrome浏览器,因为这些示例的某些HTML5组件并不适用于每个浏览器。
有jQuery的file upload的各种现成的插件。
做这种上传黑客并不是一个愉快的体验,所以人们喜欢使用现成的解决scheme。
这里有几个:
- JQueryfile upload器
- 多file upload插件
- 迷你多file upload
- jQueryfile upload
您可以在NPM上search更多项目(使用“jquery-plugin”作为关键字)或Github上。
2017更新:它仍然取决于您的人口统计使用的浏览器。
用“新”HTML5 file
API来理解的一个重要的事情是, 直到IE 10才被支持 。 如果您所瞄准的特定市场对较早版本的Windows具有高于平均水平的倾向,那么您可能无法访问它。
进入2017年,大约5%的浏览器是IE 6,7,8或9之一。如果你进入一个大公司(例如,这是一个B2B工具,或者你正在交付培训的东西),那么这个数字可能会火上浇油。 就在几个月前 – 在2016年,我处理了一个在超过60%的机器上使用IE8的公司。
所以,在你做任何事情之前: 检查你的用户使用的浏览器 。 如果你不这样做,你会学到一个快速而痛苦的教训,说明为什么“为我工作”对客户来说是不够好的。
我从2008年的答案如下。
但是,有可行的非JS方法的file upload。 您可以在页面上创build一个iframe(用CSS隐藏),然后将表单定位到该iframe。 主页面不需要移动。
这是一个“真正的”职位,所以它不是完全互动的。 如果你需要状态,你需要一些服务器端来处理。 这取决于您的服务器大量变化。 ASP.NET有更好的机制。 PHP平原失败,但您可以使用Perl或Apache修改来解决它。
如果您需要多个file upload,最好一次执行一个文件(以克服最大的file upload限制)。 将第一个表单发布到iframe中,使用上面的方法监视其进度,并在完成后将第二个表单发布到iframe,依此类推。
或者使用Java / Flash解决scheme。 他们可以用自己的post做更多的灵活性…
我build议使用Fine Uploader插件来达到这个目的。 你的JavaScript
代码将是:
$(document).ready(function() { $("#uploadbutton").jsupload({ action: "addFile.do", onComplete: function(response){ alert( "server response: " + response); } }); });
这AJAXfile uploadjQuery插件上传文件somehwere,并将响应传递给callback,没有别的。
- 它不依赖于特定的HTML,只要给它一个
<input type="file">
- 它不要求您的服务器以任何特定的方式回应
- 无论您使用多less个文件,或者页面上的位置如何,都无关紧要
– 尽量less用 –
$('#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'); } });
您不能使用XMLHttpRequest (Ajax)上传文件。 您可以使用iframe或Flash来模拟效果。 尝试SWF(Flash)上传SWFUpload 。
或者是通过iframe发布文件以获得效果的出色jQuery表单插件 。
包装为未来的读者。
asynchronousfile upload
使用HTML5
如果支持FormData和File API (两种HTML5function),则可以使用$.ajax()
方法使用jQuery上传文件。
您也可以发送没有FormData的文件,但是必须以File API必须存在的方式处理文件,以便可以使用XMLHttpRequest (Ajax)发送文件。
$.ajax({ url: 'file/destination.html', type: 'POST', data: new FormData($('#formWithFiles')[0]), // The form with the file inputs. processData: 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 )示例,请参阅“ 使用FormData对象发送文件 ”。
倒退
当不支持HTML5(不支持File API )时,唯一的其他纯JavaScript解决scheme(不包括Flash或任何其他浏览器插件)是隐藏的iframe技术,它允许在不使用XMLHttpRequest对象的情况下模拟asynchronous请求。
它包括设置一个iframe作为与文件input的forms的目标。 当用户提交请求并且文件被上传,但是响应显示在iframe中而不是重新呈现主页面时。 隐藏iframe会使整个过程对用户透明,并模拟asynchronous请求。
如果正确完成,它应该在任何浏览器上工作,但它有一些警告,如何获得iframe的响应。
在这种情况下,您可能更喜欢使用像Bifröst这样的包装器插件,它使用iframe技术,但也提供了一个jQuery Ajax传输,允许使用$.ajax()
方法发送文件 ,如下所示:
$.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到不同的回退以及一些有用的特性来缓解这个过程。 根据您的需求和要求,您可能需要考虑一个裸露的实现或者这个插件。
我一直在使用下面的脚本上传图像,碰巧工作正常。
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
来显示上传完成后的上传animation和响应。
最好的部分是当你使用这个脚本的时候,你可以发送额外的数据,比如id等。 我已经提到了脚本中的extra-data
。
在PHP级别,这将作为正常的file upload。 额外的数据可以被检索为$_POST
数据。
这里你没有使用插件和东西。 您可以根据需要更改代码。 你不是盲目地在这里编码。 这是任何jQueryfile upload的核心function。 其实是Javascript。
我遇到了一些非常强大的基于jQuery的file upload库。 检查这些:
- Plupload
- 文档: http : //www.plupload.com/docs
- jQueryfile upload
- 文档: https : //github.com/blueimp/jQuery-File-Upload
- FineUploader
- docs: http : //docs.fineuploader.com/
你可以很容易地在香草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);
你可以用jQuery .ajax()
简单地上传。
HTML:
<form id="upload-form"> <div> <label for="file">File:</label> <input type="file" id="file" name="file" /> <progress class="progress" value="0" max="100"></progress> </div> <hr /> <input type="submit" value="Submit" /> </form>
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) { // ... } }); })); });
我过去做过的最简单也最稳健的方法是简单地将隐藏的iframe标签作为目标,然后在iframe中提交,而不必重新加载页面。
这就是说,如果你不想使用插件,JavaScript或HTML以外的任何其他forms的“魔术”。 当然,你可以结合这个JavaScript或你有什么…
<form target="iframe" action="" method="post" enctype="multipart/form-data"> <input name="file" type="file" /> <input type="button" value="Upload" /> </form> <iframe name="iframe" id="iframe" style="display:none" ></iframe>
您也可以阅读iframe onLoad
的内容以获取服务器错误或成功响应,然后将其输出给用户。
Chrome,iFrame和onLoad
-note-只需要继续阅读,如果你有兴趣在上传/下载时如何设置UI阻断器
目前,Chrome在用于传输文件时不会触发iframe的onLoad事件。 Firefox,IE和Edge都会启动文件传输的onload事件。
我find的唯一解决scheme是使用cookie。
要做到这一点基本上是上传/下载开始时:
- [客户端]开始查找cookie的存在时间间隔
- [服务器端]对文件数据进行任何你需要的操作
- [服务器端]设置客户端间隔的cookie
- [客户端] Interval查看cookie并像onLoad事件一样使用它。 例如,您可以启动一个UI拦截程序,然后onLoad(或者在创buildcookie时),删除UI拦截程序。
使用这个cookie是丑陋的,但它的工作原理。
我下载了一个jQuery插件来处理Chrome的这个问题,你可以在这里find
https://github.com/ArtisticPhoenix/jQuery-Plugins/blob/master/jQuery-Plugins/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'); });
在服务器端,在传输文件数据之前,创buildcookie
setcookie('iDownloader', true, time() + 30, "/");
该插件将看到该cookie,然后触发onComplete
callback。
我发现一个解决scheme是<form>
目标隐藏的iFrame。 然后,iFrame可以运行JS以向用户显示它已完成(在页面加载中)。
我已经写在一个Rails环境 。 如果你使用轻量级的jQuery表单插件,只需要大约五行JavaScript。
挑战在于让AJAX上传工作,因为标准的remote_form_for
不理解多部分表单提交。 Rails不会发送AJAX请求返回的文件数据。
这就是jQuery表单插件的作用。
这是它的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在过去的几个星期里一直使用它,而且像冠军一样工作。
简单的Ajax上传器是另一种select:
https://github.com/LPology/Simple-Ajax-Uploader
- 跨浏览器 – 适用于IE7 +,Firefox,Chrome,Safari,Opera
- 支持多个并发上传 – 即使在非HTML5浏览器中也是如此
- 没有Flash或外部CSS – 只有一个5Kb的JavaScript文件
- 可选的内置支持完全跨浏览器的进度条(使用PHP的APC扩展)
- 灵活和高度可定制的 – 使用任何元素作为上传button,风格自己的进度指标
- 不需要任何forms,只需提供一个可用作上传button的元素
- 麻省理工学院免许可用于商业项目
用法示例:
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 Uploadify是我以前用来上传文件的另一个好的插件。 JavaScript代码如下所示:代码。 但是,新版本在Internet Explorer中不起作用。
$('#file_upload').uploadify({ 'swf': '/public/js/uploadify.swf', 'uploader': '/Upload.ashx?formGuid=' + $('#formGuid').val(), 'cancelImg': '/publichttp://img.dovov.comuploadify-cancel.png', 'multi': true, 'onQueueComplete': function (queueData) { // ... }, 'onUploadStart': function (file) { // ... } });
我已经做了很多search,我已经到了另一个解决scheme上传文件没有任何插件,只有与Ajax。 解决scheme如下:
$(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); }
这里只是如何上传文件的另一个解决scheme( 没有任何插件 )
使用简单的Javascript和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"; } ?>
这是示例应用程序
var formData=new FormData(); formData.append("fieldname","value"); formData.append("image",$('[name="filename"]')[0].files[0]); $.ajax({ url:"page.php", data:formData, type: 'POST', dataType:"JSON", cache: false, contentType: false, processData: false, success:function(data){ } });
您可以使用表单数据来发布所有的值,包括图像。
要用Jqueryasynchronous上传文件,请使用以下步骤:
步骤1在你的项目中打开Nugetpipe理器并添加包(jquery fileupload(只有你需要写在search框中它会出现并安装它))URL: https : //github.com/blueimp/jQuery-File-上传
步骤2在HTML文件中添加以下脚本,这些脚本通过运行以上包已经添加到项目中:
jquery.ui.widget.js
jquery.iframe-transport.js
jquery.fileupload.js
步骤3按照以下代码编写file upload控件:
<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 } }); };
step 5 In ready function call element file upload to initiate the process as per below:
$(document).ready(function() { uploadFile($('#upload')); });
step 6 Write MVC controller and Action as per below:
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 }; } }
您可以使用
$(function() { $("#file_upload_1").uploadify({ height : 30, swf : '/uploadify/uploadify.swf', uploader : '/uploadify/uploadify.php', width : 120 }); });
演示
Convert file to base64 using |HTML5's readAsDataURL() or some base64 encoder . Fiddle here
var reader = new FileReader(); reader.onload = function(readerEvt) { var binaryString = readerEvt.target.result; document.getElementById("base64textarea").value = btoa(binaryString); }; reader.readAsBinaryString(file);
Then to retrieve:
window.open("data:application/octet-stream;base64," + base64);
You can see a solved solution with a working demo here that allows you to preview and submit form files to the server. For your case, you need to use Ajax to facilitate the file upload to the server:
<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>
The data being submitted is a formdata. On your jQuery, use a form submit function instead of a button click to submit the form file as shown below.
$(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"); }); }); });
View more details
Sample: If you use jQuery, you can do easy to an upload file. This is a small and strong jQuery plugin, 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 } });
I hope it would be helpful
This is my solution for mvc using ajax.
<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>
and the 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(":)"); }
Look for Handling the upload process for a file, asynchronously in here: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
Sample from the link
<?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>